首页 > 解决方案 > 以派生类为参数的 C++ 基类构造函数(?)

问题描述

用例:

Vector

namespace mu {
template<std::size_t N, typename T>
class Vector {
  public:
  // ...

  template <typename... TArgs>
  Vector(TArgs... args) : data({args...}) {}

  Vector(const Vector &other) = default; // copy constructor

  // ...
  protected:
    std::array<T, N> data;
};
}

Vector2D

namespace mu {
template<typename T>
class Vector2D : public Vector<2,T> {

  public:

  using Vector<2, T>::Vector; // inherit base class constructors

  Vector2D(const Vector<2, T>& other) : Vector<2, T>(other) {}

  // Vector2D specific functions, e.g. rotation
  //...

};
}

注意:实际的类包含更多,但我将其浓缩为我认为在这里最重要的代码。

问题是我无法实现一种Vector可以从 a 构造 a 的Vector2D方法,请参见下面的代码。所有其他情况都可以正常工作。

// Example 1 (compiles)
mu::Vector<2, int> a{1, 2};
mu::Vector<2, int> b{a};

// Example 2 (compiles)
mu::Vector2D<int> c{1, 2};
mu::Vector2D<int> d{c};

// Example 3 (compiles)
mu::Vector<2, int> e{1, 2};
mu::Vector2D<int> f{e};

// Example 4 (doesn't compile)  <-- how to get this to work?
mu::Vector2D<int> g{1, 2};
mu::Vector<2, int> h{g};

当然,更普遍的问题是继承是否是构建这些类的正确方法。但我想Vector2D拥有 的所有功能以及没有Vector的附加功能。Vector

标签: c++c++11templatesinheritanceconstructor

解决方案


您的Vector类有两个构造函数:一个模板(用于值)和默认的复制构造函数。

问题:复制构造函数是首选,但前提是存在完全匹配。

b所以,初始化a

mu::Vector<2, int> a{1, 2};
mu::Vector<2, int> b{a};

复制构造函数是首选,因为a它是完全匹配的

h但是,初始化g

mu::Vector2D<int> g{1, 2};
mu::Vector<2, int> h{g};

g可以转换为 amu::Vector<2, int>不是完全匹配,因此首选模板构造函数,但模板构造函数不兼容。

一个可能的解决方案:当只有一个参数并且参数派生自mu::Vector.

例如

template <typename... TArgs,
          typename std::enable_if_t<sizeof...(TArgs) == N
                                or (not std::is_base_of_v<Vector, TArgs> && ...), int> = 0>
Vector(TArgs const & ... args) : data({args...}) {}

推荐阅读