C ++基类构造函数,将派生类作为参数(?) [英] C++ base class constructor taking derived class as argument (?)
问题描述
用例:
-
Vector
类(实现一些数学运算)和派生的Vector2D
类 理想地,两个类都应该允许复制构造".彼此
Vector
class (implementing some math) and a derivedVector2D
class- Both classes should ideally allow "copy construction" from each other
向量
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
构造 Vector
,请参见代码以下.所有其他情况都可以正常工作.
The problem is that i'm not able to implement a way such that a Vector
can be constructed from a Vector2D
, see code below. All other cases work fine.
// 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
不具备的其他功能.
Of course the more general question would be if inheritance is the right way to structure these classes. But i'd like Vector2D
to have all the functionality of Vector
and also additional functions that the Vector
does not have.
推荐答案
您的 Vector
类具有两个构造函数:一个模板(用于值)和默认的复制构造函数.
Your Vector
class has two constructor: a template one (intended for values) and the default copy constructor.
问题:首选复制构造函数,但前提是存在完全匹配.
Problem: the copy constructor is preferred but only if there is an exact match.
因此,用 a
mu::Vector<2, int> a{1, 2};
mu::Vector<2, int> b{a};
首选复制构造函数,因为 a
是完全匹配
the copy constructor is preferred because a
is an exact match
但是,用 g
mu::Vector2D<int> g{1, 2};
mu::Vector<2, int> h{g};
g
可以转换为 mu :: Vector< 2,int>
,但不是完全匹配,因此模板首选构造函数,但模板构造函数不兼容.
g
can be converted to a mu::Vector<2, int>
but isn't an exact match, so the template constructor is preferred but the template constructor is incompatible.
一种可能的解决方案:只有一个自变量且该自变量是从 mu :: Vector
派生的时,SFINAE禁用模板构造函数.
A possible solution: SFINAE disable the template constructor when the there is only one argument and the argument is derived from 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...}) {}
这篇关于C ++基类构造函数,将派生类作为参数(?)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!