以下
int i = 0;
double d{i};
给出 a 的错误(在 clang 中)或警告(在 gcc 中)narrowing conversion from 'int' to 'double'
。我发现这真的很窄,至少在我看到从 unsigned 到 double 的缩小转换之前,我感到很惊讶。
我的实际问题源于一个包含数组的类,并以最简单的方式(转发)提供用于指定数组元素的构造函数:
template<typename T, size_t N>
struct A
{
T a[N];
template<typename... E>
A(E&&... e) : a{std::forward<E>(e)...} { }
};
在这种情况下,我们有以下(现场示例):
int i = 0;
A<double, 2> x(i, 2); // ERROR for both 'i' and '2'
double y[2]{i, 2}; // ERROR for 'i' only
其中ERROR
指的是上面讨论的缩小转换。我怀疑所有这些错误都归结为开头提到的错误(double d{i};
)。是这样吗?否则,会发生什么?
无论如何,我真的很想
A<double, 2> x(i, 2);
工作,完全一样
double x(i);
作品。不幸的是,我只能使用初始化列表来初始化数组,该列表还检查缩小转换。我知道一种解决方法是在构造函数中进行显式转换:
template<typename... E>
A(E&&... e) : a{static_cast <T>(e)...} { }
或(感谢马克)
template<typename... E>
A(E&&... e) : a{static_cast <T>(std::forward<E>(e))...} { }
但这是“正确”的方式吗?它是最有效的,什么时候E
是“大”类型?