mil*_*bos 4 c++ templates language-lawyer template-argument-deduction
如果我不在函数参数列表中使用 tempate 参数(类型)-> 仅作为返回类型,则没有推论:
template <typename T>
T zero() { return 0; }
int main()
{
int x = zero();
}
Run Code Online (Sandbox Code Playgroud)
给出:
a.cpp:15:18: error: no matching function for call to ‘zero()’
int x = zero();
^
a.cpp:11:3: note: candidate: ‘template<class T> T zero()’
T zero() { return 0; }
^~~~
a.cpp:11:3: note: template argument deduction/substitution failed:
a.cpp:15:18: note: couldn't deduce template parameter ‘T’
int x = zero();
Run Code Online (Sandbox Code Playgroud)
编译的唯一方法是在尖括号中指定模板类型:
template <typename T>
T zero() { return 0; }
int main()
{
int x = zero<int>();
}
Run Code Online (Sandbox Code Playgroud)
所以我的问题是,为什么 g++可以从模板函数的参数列表中推断出类型,但不能从返回类型中推断出它(编译时编译器main也知道它,所以它知道类型)。
当模板函数在其参数列表中使用模板类型时,为模板函数提供尖括号中的类型是任意的(因为推论)?因此,作为一个好的做法,无论函数是如何声明的,我是否应该始终在花括号中提供类型?
第二个问题不太好读。用简单的话来说 -> 我应该foo<T>(arg, ...)每次都使用(提供类型),无论函数声明如何?即使它可以由编译器推断出来,但我还是会提供类型以进行良好实践?
通常不可能根据其返回类型推导出函数。但是,如果您使用自动类型转换 C++ 功能,那么您可以实现您所需要的:
template <typename T>
T zero() { return 1; }
template <>
float zero<float>() { return 3.0f; }
struct Zero
{
template<typename T>
operator T()
{
return zero<T>();
}
};
int main()
{
int x = Zero();
float y = Zero();
return x + y;
}
Run Code Online (Sandbox Code Playgroud)
首先创建临时对象 Zero(),在赋值期间我们使用转换运算符来执行零模板函数的正确特化。