将基类中的继承构造函数与自定义构造函数混合

Den*_*ank 5 c++ templates c++11

给出以下示例:

struct tag1 { };
struct tag2 { };

template<typename T>
class Base {
public:
  Base(T /*value*/) { }
  Base(tag1) { }
};

template<>
class Base<void> {
public:
  Base() { }
  Base(tag1) { }
};

template<typename T = void>
class MyClass : public Base<T> {
public:
  using Base<T>::Base;

  MyClass(tag2) : Base<T>(tag1{}) { }
};

int main() {
  {
    MyClass<> defaultConstructible;
    MyClass<> tagConstructible(tag2{});
  }
  {
    MyClass<int> valueConstructible(0);
    MyClass<int> tagConstructible(tag2{});
  }
}
Run Code Online (Sandbox Code Playgroud)

该类MyClass可以使用任何类型进行参数化,当类型T等于时,它应该是默认可构造的void,否则它可以从函数中T编写的类型构造main.

我正在使用参数依赖的基类来获取此行为(通过使用基类的构造函数).

此外,我需要将构造函数添加到接受其他参数的类层次结构中,如示例源(标记结构)中所示.

是否可以在不声明同一类中的所有构造函数的情况下执行此操作?因为将超类构造函数与自定义构造函数混合将产生以下错误消息:

main.cpp: In function 'int main()':
main.cpp:30:15: error: no matching function for call to 'MyClass<>::MyClass()'
     MyClass<> defaultConstructible;
               ^~~~~~~~~~~~~~~~~~~~
main.cpp:22:18: note: candidate: MyClass<>::MyClass(tag1)
   using Base<T>::Base;
                  ^~~~
main.cpp:22:18: note:   candidate expects 1 argument, 0 provided
main.cpp:25:3: note: candidate: MyClass<T>::MyClass(tag2) [with T = void]
   MyClass(tag2) : Base<T>(tag1{}) { }
   ^~~~~~~
main.cpp:25:3: note:   candidate expects 1 argument, 0 provided
main.cpp:20:7: note: candidate: constexpr MyClass<>::MyClass(const MyClass<>&)
 class MyClass : public Base<T> {
       ^~~~~~~
main.cpp:20:7: note:   candidate expects 1 argument, 0 provided
main.cpp:20:7: note: candidate: constexpr MyClass<>::MyClass(MyClass<>&&)
main.cpp:20:7: note:   candidate expects 1 argument, 0 provided
Run Code Online (Sandbox Code Playgroud)

演示

Bar*_*rry 2

一旦您引入了自己的构造函数,默认构造函数将不会被隐式定义 - 您尝试继承它并不重要。

您可以简单地将默认构造函数显式定义为默认值:

template<typename T = void>
class MyClass : public Base<T> {
public:
  using Base<T>::Base;

  MyClass() = default;
  MyClass(tag2) : Base<T>(tag1{}) { }
};
Run Code Online (Sandbox Code Playgroud)

在这里,MyClass<>成为默认可构造的,但MyClass<int>仍然不是,因为Base<int>不是。