模板函数特化默认参数

时间:2010-08-04 03:17:28

标签: c++ visual-c++ templates specialization visual-c++-2010

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。 但没有专业化,它做得很好。如果我更改默认参数 并且还在做专业化:

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)

由于原始问题是由于错误,现在问题变为如何解决它?

3 个答案:

答案 0 :(得分:3)

代码没有错; Comeau Online,Intel C ++ 11.1和g ++ 4.1.2成功编译。

我猜这是编译器中的一个错误。我最近提交了一个与Visual C ++ 2010编译器相关但略有不同的bug report


作为解决方法,您可以打包调用:

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 ++程序。

答案 1 :(得分:1)

正如https://stackoverflow.com/a/13566433/364084https://stackoverflow.com/a/27443191/364084所述,这是由于windows标头中定义的min和max宏。以下代码应该通过阻止宏扩展来工作:

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);
}

答案 2 :(得分:0)

成功编译...... 在     Comeau Online,http://codepad.org,EDG编译器和G ++。