簡體   English   中英

以派生類為參數的 C++ 基類構造函數 (?)

[英]C++ base class constructor taking derived class as argument (?)

用例:

  • Vector類(實現一些數學)和一個派生的Vector2D
  • 理想情況下,兩個類都應該允許彼此“復制構造”

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
  //...

};
}

注意:實際的類包含更多內容,但我將其濃縮為我認為在這里最重要的代碼。

問題是我無法實現一種可以從Vector2D構造VectorVector2D ,請參閱下面的代碼。 所有其他情況都可以正常工作。

// 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沒有的附加功能。

您的Vector類有兩個構造函數:一個模板(用於值)和默認的復制構造函數。

問題:復制構造函數是首選,但前提是存在完全匹配。

所以,用a初始化b

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

首選復制構造函數,因為a是完全匹配的

但是,用g初始化h

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

g可以轉換為mu::Vector<2, int>不是完全匹配,因此模板構造函數是首選,但模板構造函數不兼容。

一種可能的解決方案:當只有一個參數並且該參數從mu::Vector派生時,SFINAE 禁用模板構造函數。

例如

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...}) {}

撇開繼承對這個特定任務的適用性不談,失敗的直接原因是template <typename... TArgs>構造函數。 它將攔截每個不是副本的構造——並且從派生類對象構造不是副本。 這是因為從 Derived 到 Base 的轉換是一種轉換,而模板構造函數不需要轉換,所以是更好的匹配。

如果參數適合構造std::array成員,您希望將全部構造函數限制為僅包含在重載決議中。 這是 SFINAE 的標准應用程序。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM