Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 无法从初始值设定项\u列表转换为my类型,该类型具有模板可变构造函数_C++_Templates_C++17_Variadic Templates_Initializer List - Fatal编程技术网

C++ 无法从初始值设定项\u列表转换为my类型,该类型具有模板可变构造函数

C++ 无法从初始值设定项\u列表转换为my类型,该类型具有模板可变构造函数,c++,templates,c++17,variadic-templates,initializer-list,C++,Templates,C++17,Variadic Templates,Initializer List,所以,这不是我真正要做的事,我只是在玩玩。我为任何数字类型和任意坐标数的向量编写了一个Vector类。它用作向量。代码如下: #include <array> #include <functional> namespace World { template <typename NumType, unsigned char Size> class Vector { public: using CoordType = NumType; templa

所以,这不是我真正要做的事,我只是在玩玩。我为任何数字类型和任意坐标数的向量编写了一个
Vector
类。它用作
向量
。代码如下:

#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])}... } ; }
};
#包括
#包括
名称空间世界{
模板
类向量
{
公众:
使用CoordType=NumType;
模板
constexpr向量(NumTypes&…vals):值{std::forward(vals)…}
{
static_assert(sizeof…(NumTypes)=Size,“必须提供N个参数”);
}
向量(const std::数组和值):值(值){}
向量(const std::array&&values):值(std::move(values)){
const NumType&运算符[](size_t offset)const{返回值[offset];}
NumType和运算符[](大小偏移){返回值[offset];}
//!将所有值转换为新的给定类型
模板
constexpr Vector Convert()const{return Convert(std::make_index_sequence{});}
//!通过转换函数转换所有值
模板
向量转换(const std::function&callback)const{return Convert(std::make_index_sequence{},callback);}
std::数组值;
私人:
//!将所有值转换为新的给定类型
模板
constexpr向量转换(std::index_序列)const{return{{static_cast(values[Is])}…};}
//!通过转换函数转换所有值
模板
向量转换(std::index_序列,const std::function&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;
}
使用名称空间世界;
使用Vector3D=矢量;
使用Vector3Int=Vector;
#包括
int main()
{
常量向量3d src{1.4,2.5,3.6};
const Vector3Int target=src.Convert([](双val){return(int)std::round(val);});
返回0;
}
这里的问题是,当编译转换函数时,生成的新值以
std::initializer\u list
的形式出现。出于某种原因,这不符合构造函数
向量(NumTypes&&…vals)的条件
。现在我不希望有初始值设定项列表构造函数-预期参数的数量不是可变的,它必须是
大小
模板参数所说的任何值

那么如何解决这个问题呢?我如何将
std::initializer\u list
转换成
NumTypes&&…vals
是什么


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

< > >代码>转换<代码>,你有参数包<代码> < /COD>,你想使用它与<代码>回调< /代码>和<代码>值< /> > < < 参数包扩展“扩展为零个或多个模式的逗号分隔列表”,因此,当与问题中的值一起使用时,您将得到以下结果:

是…

0, 1, 2
值[Is]…
=>
值[0]、值[1]、值[2]

1.4, 2.5, 3.6
1, 3, 4
回调(值[Is])…
=>
回调(值[0])、回调(值[1])、回调(值[2])

您希望创建一个大括号的init列表,如下所示:

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

模板
矢量
转换(标准::索引_序列,
const std::函数和回调)const
{
返回{callback(值[Is])…};
}

我没有仔细查看它,但是
Convert
函数是否应该像这样返回:
返回{callback(values[Is])…};
?OT:首先,常量右值引用没有意义(特别是,如果您以后试图“移动”它们)第二,基本类型的完美转发也没有意义。对于
int
double
@tedlynmo这样的类型,复制和移动没有区别。你真是个天才!但是点的位置是基于其他代码的,当它们位于括号后面时,它们会起作用……你可以发布一个ans吗这解释了
{{x..}}
{{x}..}
之间的区别吗?@TomášZato(简化:
返回{callback(值[Is])…};
也应该有效).我写不出答案。一个3小时的会议现在开始。我将把它交给其他人。:-@TomášZato,我看到没有人捡到球,所以我尝试用例子来解释。我觉得我自己解释得不好,所以我希望其他人能给出更好的答案(或者在我的答案上改进,如果可以补救的话)
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])...};
}