可变参数模板和初始化程序列表类型差异缩小

时间:2019-02-05 12:21:47

标签: 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... } {}

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<int,2> twoi = { 1, 2.1 }; //An int and a double

但不是:

Vec<int,2> twoi2(1,2.1); //conversion from 'double' to 'int' requires a narrowing conversion

这似乎并不直观。对于Initializer列表,它只是执行转换,而在扩展模板时,它应该只交出转换为int的double。

如果我正确的话,这也是应该扩展功能的地方:

std::array< int, 2> elements_ = { 1.2,1};

编译得很好。

是否可以修改此构造函数以忽略转换?

Visual Studios 2015 Update 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 个答案:

答案 0 :(得分:0)

最终找到答案。

简单的答案是,需要进行一次转换。有些编译器可以使用它,并且可以直接进行转换,有些则不能,并且抱怨它是不可能的。解决方法是将偷偷摸摸的演员表拖到构造函数中。

template <typename... U>
    Vec(const U&... ts) 
        : elements_{(T)(ts)... } {
    }

然后,所有内容都将扩展为:elements _((T)ts [1] ... ext。