无法从 initializer_list 转换为我的类型,该类型具有模板化可变参数构造函数

Cannot convert from initializer_list to my type, which has templated variadic constructor

所以,这并不是我 必须 做的事情,我只是在玩。我为任何数字类型和任意数量的坐标的向量写了一个 Vector class 。它用作 Vector<NumericType, [num of coords]>。这是代码:

#include <array>
#include <functional>

namespace World {

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


  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(const 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]; }

  //! Converts all values to new given type
  template <typename NewType>
  constexpr Vector<NewType, Size> Convert() const { return Convert<NewType>(std::make_index_sequence<Size>{}); }
  //! Converts all values via the conversion function
  template <typename NewType>
  Vector<NewType, Size> Convert(const std::function<NewType(NumType)>& callback) const { return Convert<NewType>(std::make_index_sequence<Size>{}, callback); }

  std::array<NumType, Size> values;

private:
  //! Converts all values to new given type
  template <typename NewType, std::size_t ... Is>
  constexpr Vector<NewType, Size> Convert(std::index_sequence<Is...>) const { return { { static_cast<NewType>(values[Is])}... }; }
  //! Converts all values via the conversion function
  template <typename NewType, std::size_t ... Is>
  Vector<NewType, Size> Convert(std::index_sequence<Is...>, const std::function<NewType(NumType)>& callback) const { return { { callback(values[Is])}... } ; }
};

现在我要做的是确保上面声明的转换函数正常工作。使用思路是这样的:

using namespace World;
using Vector3D = Vector<double, 3>;
using Vector3Int = Vector<int, 3>;

#include <cmath>

int main()
{
  const Vector3D src{ 1.4, 2.5, 3.6 };
  const Vector3Int target = src.Convert<int>([](double val) { return (int)std::round(val); });
  return 0;
}

这里的问题是编译转换函数时,生成的新值以std::initializer_list<NewType>的形式出现。出于某种原因,这不符合构造函数 Vector(NumTypes&&... vals) 的条件。现在我不想有一个初始化列表构造函数 - 预期参数的数量不是可变的,它必须是 Size 模板参数所说的任何内容。

那么如何解决这个问题呢?我怎样才能将 std::initializer_list 转换为 NumTypes&&... vals 是什么?

我必须承认,我并不确切地知道我在做什么,我正在努力提高我的 C++ 知识。

Convert 中,您有参数包 Is,您希望将其与 callbackvalues 结合使用。

参数包扩展“扩展为以逗号分隔的零个或多个模式列表”,因此当与问题中的值一起使用时,您将得到:

Is...

0, 1, 2

values[Is]... => values[0], values[1], values[2]

1.4, 2.5, 3.6

callback(values[Is])... => callback(values[0]), callback(values[1]), callback(values[2])

1, 3, 4

并且您想像这样创建一个 braced-init-list

{callback(values[0]), callback(values[1]), callback(values[2])}
// =>
{1, 3, 4}

所以:

template <typename NewType, std::size_t... Is>
Vector<NewType, Size> 
        Convert(std::index_sequence<Is...>, 
                const std::function<NewType(NumType)>& callback) const
{
    return {callback(values[Is])...};
}