使用模板时缺少默认构造函数

Posted

技术标签:

【中文标题】使用模板时缺少默认构造函数【英文标题】:missing default constructor while using templates 【发布时间】:2011-10-28 13:53:18 【问题描述】:

我们在使用类模板时遇到问题,该类模板本身在其某些成员函数中使用函数对象。 VS2010 编译器的错误信息是:

错误 C2512: 'SimpleFunctor::SimpleFunctor' : 没有合适的默认值 构造函数可用

重现此的缩小代码如下:

// myfunctor.h

class SimpleFunctor

  private:
    SimpleFunctor( const SimpleFunctor& );
    SimpleFunctor& operator=( const SimpleFunctor& );
  public:
    bool operator()()  return true; 
; 

// mytemplate.h

#include "myfunctor.h"

template< typename T >
class Test

  private:
    Test( const Test& );
    Test& operator=( const Test& );
  public:
    Test()

    void testFunction( T parameter )
    
      bool result = SimpleFunctor()();
    
;

// main.cpp

#include "HK_Template.h"

int main()

  Test< int > obj;
  obj.testFunction( 5 );

  return 0;

这个例子产生了上面的错误消息,这似乎是正确的,因为将默认构造函数添加到类 SimpleFunctor 中,例如:

SimpleFunctor() 

修正错误。

那么问题来了,为什么编译器不生成默认构造函数呢?

【问题讨论】:

+1 提出一个很好的问题 【参考方案1】:

一旦您自己定义了任何构造函数,包括复制构造函数,编译器就不再生成默认构造函数。

(另一方面,如果您不提供,则默认生成复制/移动构造函数,但须遵守某些规则。)

【讨论】:

哦,我正要提交同样的答案! +1来自我。 没错,只是为了说明清楚,这种行为与模板无关,它是一般的 C++ 规则【参考方案2】:

编译器只在你不定义的时候提供一个默认的构造函数 任何构造函数。由于您已经声明了用户定义的副本 构造函数,编译器不会提供它。

看起来你声明复制构造函数的唯一原因是 使其私有化,从而禁用它。在这种情况下,一个更好的 解决方案可能是从boost::noncopyable 继承,它具有 效果相同,但不会阻止编译器生成 默认构造函数。

【讨论】:

或者explicitly delete复制构造函数。 @Als 仅当您的编译器支持 C++11 时才有可能。对于大多数开发者来说,这不是一个选择。

以上是关于使用模板时缺少默认构造函数的主要内容,如果未能解决你的问题,请参考以下文章

netstandard 1.5 中缺少 StackTrace 的默认构造函数

使用带有 std::void_t 的类模板检查默认构造函数

如何允许我的模板化 Vector 允许没有默认(空)构造函数的类型?

使用枚举和模板参数正确定义显式默认构造函数

使用模板类数据成员的c ++“没有适当的默认构造函数可用”错误

当实例缺少公共构造函数时,有啥方法可以从 .NET 中的 AppDomain 创建实例?