2
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)

由于最初的问题是由于错误,现在问题变成了如何解决它?

4

3 回答 3

3

代码没有问题;Comeau Online、Intel C++ 11.1、g++ 4.1.2 编译成功。

我猜这是编译器中的一个错误。我最近提交了一份针对 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>())
{
}

丑陋的?相当。


针对您在 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++ 程序。

于 2010-08-04T03:25:58.723 回答
2

正如在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);
}
于 2016-10-10T04:51:48.130 回答
0

它已成功编译...在 Comeau Online、http://codepad.org、EDG编译器和 G++ 中。

于 2010-08-04T05:38:10.443 回答