C++ 可变模板和初始值设定项列出类型缩小差异
所以这没有任何意义 在本课程中:C++ 可变模板和初始值设定项列出类型缩小差异,c++,variadic-templates,initializer-list,C++,Variadic Templates,Initializer List,所以这没有任何意义 在本课程中: template< typename T, int nDimensions = 2 > class Vec { private: std::array< T, nDimensions > elements_; public: typedef T ValueType; Vec() : elements_() {} template <typename... U> Vec(U... ts) : elements_{ ts..
template< typename T, int nDimensions = 2 >
class Vec {
private:
std::array< T, nDimensions > elements_;
public:
typedef T ValueType;
Vec() : elements_() {}
template <typename... U>
Vec(U... ts) : elements_{ ts... } {}
Vec(const std::initializer_list<T>& values){
std::copy(values.begin(), values.end(), elements_.begin());
}
template <typename T2, int nDimension2>
Vec(Vec<T2, nDimension2> const& copy){
for (int i = 0; i < nDimensions; i++){
this->elements_[i] = (T)static_cast<T2>(copy[i]);
}
}
};
模板
Vec类{
私人:
std::数组元素;
公众:
typedef T ValueType;
Vec():元素
模板
向量(U…ts):元素{ts…}{}
Vec(常数标准::初始值设定项列表和值){
std::copy(values.begin()、values.end()、elements\uz.begin());
}
模板
Vec(Vec常量和副本){
对于(int i=0;i元素(i)=(T)静态(复制[i]);
}
}
};
为什么这样做很好:
Vec<int,2> twoi = { 1, 2.1 }; //An int and a double
vectwoi={1,2.1}//一个int和一个double
但不是:
Vec<int,2> twoi2(1,2.1); //conversion from 'double' to 'int' requires a narrowing conversion
vectwoi2(1,2.1)//从“double”到“int”的转换需要缩小转换范围
这似乎并不直观。对于初始值设定项列表,它只是执行转换,而另一方面,当模板展开时,它应该只移交转换为int的double
如果我是正确的,这也是函数应该扩展的内容:
std::array< int, 2> elements_ = { 1.2,1};
std::array元素{1.2,1};
它编译得很好
有没有办法修改此构造函数以忽略转换
Visual Studio 2015更新3构建:
1>------ Build started: Project: MathTests, Configuration: Debug Win32 ------
1> Source.cpp
1>d:\projects\stevenstuff\mathtests\source.cpp(12): warning C4838: conversion from 'double' to 'int' requires a narrowing conversion
1>d:\projects\stevenstuff\mathtests\source.cpp(12): warning C4244: 'initializing': conversion from 'double' to 'int', possible loss of data
1>d:\projects\stevenstuff\util\vec\include\vec.h(19): error C2397: conversion from 'const double' to 'int' requires a narrowing conversion
1> d:\projects\stevenstuff\mathtests\source.cpp(10): note: see reference to function template instantiation 'Vec<int,2>::Vec<double,int>(const double &,const int &)' being compiled
1>----构建已启动:项目:MathTests,配置:调试Win32------
1> Source.cpp
1> d:\projects\stevenstuff\mathtests\source.cpp(12):警告C4838:从“double”到“int”的转换需要缩小转换范围
1> d:\projects\stevenstuff\mathtests\source.cpp(12):警告C4244:“正在初始化”:从“double”转换为“int”,可能会丢失数据
1> d:\projects\stevenstuff\util\vec\include\vec.h(19):错误C2397:从“const double”到“int”的转换需要缩小转换范围
1> d:\projects\stevenstuff\mathtests\source.cpp(10):注意:请参阅正在编译的函数模板实例化“Vec::Vec(constdouble&,constint&)”的参考
终于找到了答案
简单的回答是,需要进行转换。有些编译器可以直接使用它,而有些编译器则不这样做,并抱怨这是不可能的。解决的办法是偷偷地向构造器中插入一个石膏
template <typename... U>
Vec(const U&... ts)
: elements_{(T)(ts)... } {
}
模板
Vec(常数U和…ts)
:元素{(T)(ts)…}{
}
然后所有内容都展开为:elements_((T)ts[1]…ext.我得到了
={1,2.1}
的缩小错误和的缩小警告(1,2.1)
使用gcc8.1。演示:是的,@TrebuchetMS我一直在谷歌上搜索,而且这种行为在不同版本之间似乎也有很大变化。仅供参考:我正在使用visual Studio进行编译。您使用的是什么版本的MSV?C++11支持直到2015年更新3才被认为是完整的。MSVS 2017未能按预期编译这两个版本。@NathanOliver更新