【问题标题】:default arguments for templated function [duplicate]模板化函数的默认参数
【发布时间】:2011-09-17 06:10:46
【问题描述】:

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

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

【问题讨论】:

  • 不幸的是,C++03 14.8.2.4/17 说:A template type-parameter cannot be deduced from the type of a function default argument。所以需要像 iammilind's answer 这样的解决方法。
  • @Ise Wisteria,准确地回答了我的问题,以答案的形式提出,我会接受。
  • @ecatmur 问题如何与一年新的问题重复?
  • @Adam 新问题有更好的标题和更好的答案。

标签: c++ templates


【解决方案1】:

话虽如此,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.

【讨论】:

    【解决方案2】:

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


    参考资料:

    C++03 标准:14.1.9:

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

    C++11:14.1.9:

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

    【讨论】:

    • 你知道它们在 C++11 中是否允许吗?
    • 我刚刚看到您的编辑,这似乎不适用于我的情况。我不想为模板参数指定默认值,我想为类型恰好被模板化的常规参数指定默认值。您的报价适用于我想说template &lt;class HANDLER=DefaultHandler&gt;的情况
    • 这并没有回答这个问题。该代码有一个默认的函数模板函数参数。它在 C++03 和 C++11 中都有效。问题是,为什么它不起作用?
    【解决方案3】:

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

    模板type-parameter不能从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 也有相同的规格, 这似乎在新标准中没有改变......

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-11
      • 2014-05-18
      • 2020-07-10
      • 2015-07-08
      • 1970-01-01
      • 2013-09-13
      相关资源
      最近更新 更多