C++中模板的默认参数

Default argument with template in C++

我正在设计一个界面,用户可以通过该界面定义一个 class 来告诉他们想做什么。
代码如下所示,

#include <stdio.h>

class Dummy{
public:
    void do(){ printf("do nothing\n"); }
};

class Task{
public:
    void do(){ printf("do something\n"); }
};

template <class TASK>
void func(TASK &task = Dummy()){
    task.do();
}

int main(){
    func(); // do nothing
    Task task;
    func(task); // do something
}

如何让它发挥作用?

主要问题是这个 func 参数:

TASK &task = Dummy()

只有const才行。发生这种情况是因为对类型的非常量左值引用无法绑定到临时对象。

但是如果你可以在那里使用const,你可以轻松解决你的问题:

class Dummy{
public:
    void doit() const { printf("do nothing\n"); }
};

class Task{
public:
    void doit() const { printf("do something\n"); }
};

template <class TASK = Dummy>
void func(const TASK &task = TASK()){
    task.doit();
}

int main(){
    func(); // do nothing
    Task task;
    func(task); // do something
}

首先,不要有一个名为 do 的标识符(函数命名),因为 do 是一个语言关键字。将其用作标识符是可诊断的错误。除了更改函数名称外别无选择。

其次,func() 的参数 will 需要是 const,因为传递的默认值是临时值(只能绑定到 const 引用) .这也意味着您在 类 中的函数需要 const 合格。

第三,当调用func() 时,有必要传递一些信息,以便编译器计算出如何实例化模板。如果您想在调用站点(即 func())完全不传递任何信息,那么您需要有一个非模板化重载。

第四,使用C++流而不是CI/O。

 class Dummy
 {
    public:
       void do_it() const { std::cout << "do nothing\n"; }
 };

 class Task
 {
    public:
       void do_it() const { std::cout << "do something\n"; }
 };

 template <class TASK>
  void func(const TASK &task)
  {
     task.do_it();
  }

  void func()
  {
      func(Dummy());
  }

  int main()
  {
     func(); // do nothing
     Task task;
     func(task); // do something
  }

方案二是将上面两个版本的func()替换为

 template <class TASK = Dummy>
  void func(const TASK &task = TASK())
  {
     task.do_it();
  }