模板化函数的默认参数

时间:2011-09-17 06:10:47

标签: c++ templates

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

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

3 个答案:

答案 0 :(得分:3)

已经说过当前标准中不允许template的默认参数。以下是解决问题的简单方法:

template <class HANDLER>
void action(HANDLER h) {
    std::cout << h.foo() << std::endl;
}
void action() {  // wrapper
  action(DefaultHandler()); // call the desired funciton
}

提供一个包装器,它会使action()的默认参数生效。 Demo

答案 1 :(得分:2)

C ++ 03中不允许使用模板函数的默认参数,但在C ++ 11中是允许的。


<强>参考文献:

C ++ 03标准:14.1.9:

  

默认模板参数是在模板参数中=后指定的模板参数(14.3)。可以为任何类型的模板参数(类型,非类型,模板)指定Adefault模板参数。可以在类模板声明或类模板定义中指定默认模板参数。 不应在函数模板声明或函数模板定义中指定默认模板参数,也不应在类模板成员定义的template-parameter-list中指定。不应在朋友模板声明中指定默认模板参数。

C ++ 11:14.1.9:

  

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

答案 2 :(得分:0)

不幸的是,C ++ 03 14.8.2.4/17说:

  

无法从a的类型推导出模板类型参数   函数默认参数

并提供如下示例:

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

因为N3290 14.8.2.5/19也说明了相同的规格, 这似乎不会改变新标准......