简体   繁体   English

我的可变参数模板构造函数隐藏了复制构造函数,防止 class 被复制

[英]My variadic templated constructor hides copy constructor, preventing the class to be copied

I made a Vector<numType, numberOfCoords> class.我制作了一个Vector<numType, numberOfCoords> class。 I was happy with it, it's kinda weird but it seemed to work at the start.我对此很满意,这有点奇怪,但它似乎在一开始就奏效了。 But I just found out copying the vectors is impossible.但我刚刚发现复制向量是不可能的。

The reason is that to allow the number of coordinates to be a template, there is a templated variadic constructor which expects the right number of coordinates.原因是为了让坐标数成为模板,有一个模板化的可变参数构造函数,它需要正确的坐标数。

This is what it looks like, with the utility math methods removed:这是它的样子,删除了实用数学方法:

template <typename NumType, unsigned char Size>
class Vector
{
public:
  using CoordType = NumType;

  //Vector(const Vector& v) : values(v.values) {}
  //Vector(Vector&& v) : values(std::move(v.values)) {}

  template<typename... NumTypes>
  constexpr Vector(NumTypes&&... vals) : values{ std::forward<NumTypes>(vals)... }
  {
    static_assert(sizeof...(NumTypes) == Size, "You must provide N arguments.");
  }

  Vector(const std::array<NumType, Size>& values) : values(values) {}
  Vector(std::array<NumType, Size>&& values) : values(std::move(values)) {}

  const NumType& operator[](size_t offset) const { return values[offset]; }
  NumType& operator[](size_t offset) { return values[offset]; }
  //Vector& operator=(const Vector& other) { values = other.values; }
  //Vector& operator=(Vector&& other) { values = std::move(other.values); }

  std::array<NumType, Size> values;

};

As you can see - now commented out - I did try to implement copy and move and assignment operations manually.如您所见 - 现在已注释掉 - 我确实尝试手动实现复制、移动和分配操作。 It had no effect, the error is always along the lines of:它没有效果,错误总是沿着:

cannot convert ‘Vector<int, 3>’ to ‘int’ in initialization

This is because it is still trying to use the variadic constructor, instead of the copy constructor.这是因为它仍在尝试使用可变参数构造函数,而不是复制构造函数。

Here is a full working broken sample: https://ideone.com/Jz86vP这是一个完整的工作损坏示例: https://ideone.com/Jz86vP

You might:你可能会:

  • SFINAE your variadic constructor, for example: SFINAE 你的可变参数构造函数,例如:

     template <typename... NumTypes, std::enable_if_t<sizeof...(NumTypes) == Size && std::conjunction<std::is_same<NumType, NumTypes>::value, int> = 0> constexpr Vector(NumTypes&&... vals): values{ std::forward<NumTypes>(vals)... } { }

    Note: std::conjunction is C++17, but can be done in C++14.注意: std::conjunction是 C++17,但可以在 C++14 中完成。

  • or prepend a tag:或添加标签:

     template <typename... NumTypes> constexpr Vector(struct SomeTag, NumTypes&&... vals): values{ std::forward<NumTypes>(vals)... } { }
  • or redesign the class, for example, something like:或重新设计 class,例如:

     template <typename T, std::size_t> using always_type = T; template <typename NumType, typename Seq> class VectorImpl; template <typename NumType, std::size_t... Is> class VectorImpl<NumType, std::index_sequence<Is...>> { public: using CoordType = NumType; VectorImpl(const VectorImpl&) = default; VectorImpl(VectorImpl&&) = default; VectorImpl& operator=(const VectorImpl&) = default; VectorImpl& operator=(VectorImpl&&) = default; constexpr VectorImpl(always_type<NumType, Is>... vals): values{ std::forward<NumType>(vals)... } { } VectorImpl(const std::array<NumType, sizeof...(Is)>& values): values(values) {} VectorImpl(std::array<NumType, sizeof...(Is)>&& values): values(std::move(values)) {} const NumType& operator[](size_t offset) const { return values[offset]; } NumType& operator[](size_t offset) { return values[offset]; } std::array<NumType, sizeof...(Is)> values; }; template <typename T, std::size_t N> using Vector = VectorImpl<T, std::make_index_sequence<N>>;

    Demo演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM