Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 模板化函数的默认参数_C++_Templates - Fatal编程技术网

C++ 模板化函数的默认参数

C++ 模板化函数的默认参数,c++,templates,C++,Templates,我有一个函数,它接受运算符对象作为参数。这个操作符被视为回调函数。此运算符对象的类型是模板参数。如何为其指定默认参数 #include <iostream> template<class IT, class NT> class A { public: class DefaultHandler { public: NT foo() { return NT(); } }; template <class

我有一个函数,它接受运算符对象作为参数。这个操作符被视为回调函数。此运算符对象的类型是模板参数。如何为其指定默认参数

#include <iostream>

template<class IT, class NT>
class A
{
    public:
    class DefaultHandler
    {
    public:
        NT foo() { return NT(); }
    };

    template <class HANDLER>
    void action(HANDLER h = DefaultHandler()) // This default parameter is accepted by the compiler but appears to have no effect
    {
        std::cout << h.foo() << std::endl;
    }
};

int main()
{
    A<int, double> a;
    // I want this to be legal:
    a.action(); // error: no matching function for call to ‘A<int, double>::action()’

    //a.action(A<int, double>::DefaultHandler()); // Works
    return 0;
}
#包括
模板
甲级
{
公众:
类DefaultHandler
{
公众:
NT foo(){return NT();}
};
模板
void action(HANDLER h=DefaultHandler())//编译器接受此默认参数,但似乎没有效果
{

std::cout模板函数的默认参数在C++03中不允许,但在C++11中允许


参考文献:

C++03标准:14.1.9:

默认模板参数是在模板参数中的=之后指定的模板参数(14.3)。可以为任何类型的模板参数(类型、非类型、模板)指定默认模板参数默认模板参数可以在类模板声明或类模板定义中指定。默认模板参数不能在函数模板声明或函数模板定义中指定,也不能在类模板成员定义的模板参数列表中指定。默认模板参数好友模板声明中不应指定默认值。

C++11:14.1.9:

默认模板参数是在模板参数中的=之后指定的模板参数(14.3)。可以为非模板参数包(14.5.3)的任何类型的模板参数(类型、非类型、模板)指定无故障模板参数。默认模板参数可以在模板定义中指定。默认模板参数不应在类模板成员定义的模板参数列表中指定,该类模板出现在成员的类之外。默认模板参数 不应在友元类模板声明中指定。如果友元函数模板声明指定了默认模板参数,则该声明应为定义,并且应为翻译单元中函数模板的唯一声明。


如上所述,
模板的默认参数在当前标准中是不允许的。下面是一个简单的解决方法:

template <class HANDLER>
void action(HANDLER h) {
    std::cout << h.foo() << std::endl;
}
void action() {  // wrapper
  action(DefaultHandler()); // call the desired funciton
}
模板
无效操作(处理程序h){

不幸的是,C++0314.8.2.4/17说:

无法从模板的类型推断模板类型参数 函数默认参数

并提供了如下示例:

template <class T> void f(T = 5, T = 7);
void g()
{
    f(1);                   // OK: call f<int>(1,7)
    f();                    // error: cannot deduce T
    f<int>();               // OK: call f<int>(5,7)
}
模板空隙f(T=5,T=7);
void g()
{
f(1);//确定:调用f(1,7)
f();//错误:无法推断T
f();//确定:调用f(5,7)
}
因为N3290 14.8.2.5/19也规定了相同的规范,
这在新标准中似乎没有改变…

你知道C++11中是否允许它们吗?我刚刚看到你的编辑,这似乎不适用于我的情况。我不想为模板参数指定默认值,我想为类型恰好是模板化的常规参数指定默认值。你的引用适用于以下情况:我想说的是
template
这并没有回答问题。代码有一个默认的函数模板函数参数。它在C++03和C++11中都有效。问题是,为什么它不起作用?不幸的是,C++03 14.8.2.4/17说:
模板类型参数不能从函数默认参数的类型推导出来ode>。因此需要一些变通方法,比如iammilind的答案。@Ise Wisteria,准确回答了我的问题,以答案的形式提出,我会接受它。@ecatmur一个问题怎么会是一个比一年新的问题的重复?@Adam这个新问题有更好的标题和更好的答案。