C ++基类构造函数,将派生类作为参数(?) [英] C++ base class constructor taking derived class as argument (?)

查看:65
本文介绍了C ++基类构造函数,将派生类作为参数(?)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

用例:

  • Vector 类(实现一些数学运算)和派生的 Vector2D
  • 理想地,两个类都应该允许复制构造".彼此
  • Vector class (implementing some math) and a derived Vector2D 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆