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更新