template <typename T> void function(T arg1,
T min = std::numeric_limits<T>::min(),
T max = std::numeric_limits<T>::max())
{
}
template <> void function<int>(int arg1, int min,int max)
{
}
int main(int argc,char* argv[])
{
function<int>(1);
}
它在 ::
上的函数默认参数行上给出语法错误 C2689 和 C2059 token 。
但没有特化,它做得很好。如果我更改默认参数
并且仍在做特化:
template <typename T> void function(T arg1,
T min = T(0),
T max = T(1))
{
}
template <> void function<int>(int arg1, int min,int max)
{
}
问题也解决了。
现在如果我像这样使用它:function<int>(1,2,3);
或function<float>(1.0f)
好吧,看来如果模板函数是专门的,我们在调用它时必须重写默认参数?
但在我的第二种情况下,我替换 std::numeric_limits<T>::..
与 T(..)
调用 function<int>(1)
时没有语法错误,这是为什么?
(我使用的是 Visual Studio 2010 x64)
由于原来的问题是由于错误,现在的问题改为如何解决它?
最佳答案
代码没有任何问题; Comeau Online、Intel C++ 11.1、g++ 4.1.2均编译成功。
我猜这是编译器中的一个错误。我最近提交了一个相关的,但略有不同的bug report针对 Visual C++ 2010 编译器。
作为解决方法,您可以包装调用:
template <typename T>
T get_limits_min() { return std::numeric_limits<T>::min(); }
template <typename T>
T get_limits_max() { return std::numeric_limits<T>::max(); }
template <typename T> void function(T arg1,
T min = get_limits_min<T>(),
T max = get_limits_max<T>())
{
}
丑吗?完全正确。
我发布了以下内容来回复 the bug you reported on Microsoft Connect:
主模板必须有一个具有默认参数值的参数。默认参数值必须是不在全局命名空间中的类模板的成员函数。
以下是可重现的最少代码:
namespace N
{
template <typename T>
struct S
{
static T g() { return T(); }
};
}
template <typename T> void f(T = N::S<T>::g()) { }
template <> void f<>(int) { }
int main()
{
f<int>();
}
编译器在定义主模板的行上发出以下错误:
error C2589: '::' : illegal token on right side of '::'
error C2059: syntax error : '::'
有趣的是,如果类模板位于全局命名空间中,还会出现另一个问题。给出以下代码:
template <typename T>
struct S
{
static T g() { return T(); }
};
template <typename T> void f(T = ::S<T>::g()) { }
template <> void f<>(int) { }
int main()
{
f<int>();
}
编译器在定义主模板的行上发出以下错误:
error C2064: term does not evaluate to a function taking 0 arguments
这两个示例测试用例都是格式良好的 C++ 程序。
关于c++ - 模板函数特化默认参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3402338/