模板函数特化默认参数

发布于 2024-09-12 22:34:57 字数 1006 浏览 5 评论 0原文

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(1,2,3);function(1.0f) 就可以了,所以看起来如果模板函数是专门的,我们在调用它时必须重写默认参数吗?

但在我的第二种情况下,我用 T(..) 替换 std::numeric_limits::.. ,调用 function< 时没有语法错误;int>(1),这是为什么呢?

(我使用的是 Visual Studio 2010 x64),

因为最初的问题是由于 bug,现在的问题改为如何解决它?

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

it give syntax error C2689 and C2059 on function default argument line on :: token.
but without specialization, it doing fine. and if I change default argument
and still doing specialization:

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

the problem gone too.

now if I use it like this: function<int>(1,2,3); or function<float>(1.0f) its fine, so it seems that if template function is specialized, we must rewrite the default argument when call it?

but on my second case, where i replace std::numeric_limits<T>::.. with T(..) there no syntax error when calling function<int>(1), why is that?

(I'am using Visual Studio 2010 x64)

as original problem is because of bug, the question now changed to how to workaround it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

明天过后 2024-09-19 22:34:57

代码没有任何问题; 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 上报告的错误:< /a>

主模板必须有一个具有默认参数值的参数。默认参数值必须是不在全局命名空间中的类模板的成员函数。

以下是要重现的最少代码:

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

There is nothing wrong with the code; Comeau Online, Intel C++ 11.1, and g++ 4.1.2 compile it successfully.

I would guess that it is a bug in the compiler. I recently submitted a related, but slightly different bug report against the Visual C++ 2010 compiler.


As a workaround, you can wrap the calls:

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>())
{
}

Ugly? Quite.


I posted the following in response to the bug you reported on Microsoft Connect:

The primary template must have a parameter that has a default argument value. The default argument value must be a member function of a class template not in the global namespace.

The following is minimal code to reproduce:

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

The compiler emits the following errors, both on the line where the primary template is defined:

error C2589: '::' : illegal token on right side of '::'
error C2059: syntax error : '::'

Interestingly, there is another issue if the class template is in the global namespace. Given the following code:

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

The compiler emits the following error on the line on which the primary template is defined:

error C2064: term does not evaluate to a function taking 0 arguments

Both of these example test cases are well-formed C++ programs.

不离久伴 2024-09-19 22:34:57

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

As answered here at https://stackoverflow.com/a/13566433/364084 and https://stackoverflow.com/a/27443191/364084, this is due to min and max macro defined in windows header. The following code should work by preventing the macro expansion:

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);
}
薄暮涼年 2024-09-19 22:34:57

已经编译成功了...

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

It is succeesfully compiled...
in
Comeau Online ,http://codepad.org,EDG Compiler ,and G++ .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文