如何从函数返回类型推导函数模板参数?

huangapple go评论83阅读模式
英文:

how to deduce function template argument from function return type?

问题

我明白float可以被转换为double甚至int;是否可能根据所请求的返回类型自动实例化get<T>?如果可以,如何实现?

英文:

Example:

template&lt;typename T&gt;
T get() {
	return T{};
}

void test() {
	float f = get();//requires template argument; e.g. get&lt;float&gt;();
}

I understand that float can be converted to double or even int; is it possible to have get&lt;T&gt; instanciated automatically based on the requested return type? If so how?

答案1

得分: 8

不,仅在转换运算符模板的情况下才会从返回类型进行模板参数推断:

struct A {
    template<typename T>
    operator T() {
        //...
    }
};

//...

// 调用`operator T()`,其中`T == float`,将`A` 临时对象转换为`float`
float f = A{};

这也可以用于使get返回A对象,以便float f = get();语法也能正常工作。但是,是否使用此机制如您所愿是一个问题。存在许多注意事项,很容易变得难以理解。例如,在auto f = get();中会发生什么?在调用g(get())中如果函数g有多个重载会发生什么?等等。

相反,将类型说明符移到模板参数上,您就不必重复自己:

auto f = get<float>();
英文:

No, template argument deduction from the return type works only for conversion operator templates:

struct A {
    template&lt;typename T&gt;
    operator T() {
        //...
    }
};

//...

// calls `operator T()` with `T == float` to convert the `A` temporary to `float`
float f = A{};

This can also be used to have get return the A object so that float f = get(); syntax will work as well.
However, it is questionable whether using this mechanism as you intent is a good idea. There are quite a few caveats and can easily become difficult to follow. For example what happens in auto f = get();? What happens if there are multiple overloads of a function g in a call g(get())? Etc.

Instead move your type specifier to the template argument and you wont have to repeat yourself:

auto f = get&lt;float&gt;();

huangapple
  • 本文由 发表于 2023年1月9日 00:27:02
  • 转载请务必保留本文链接:https://go.coder-hub.com/75049452.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定