以下
int i = 0;
double d{i};
のエラー (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)...} { }
};
この場合、次のようになります ( live example )。
int i = 0;
A<double, 2> x(i, 2); // ERROR for both 'i' and '2'
double y[2]{i, 2}; // ERROR for 'i' only
whereERROR
は、前述の縮小変換を指します。これらのエラーはすべて、最初に述べたもの ( double d{i};
) に集約されるのではないかと思います。そうですか?そうでなければ、何が起こっていますか?
とにかく、私は本当に欲しいです
A<double, 2> x(i, 2);
まさに同じように働く
double x(i);
動作します。残念ながら、初期化リストを使用して配列を初期化することしかできません。これは、縮小変換もチェックします。回避策の 1 つは、コンストラクターで明示的なキャストを行うことです。
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
そして、「大きな」タイプはいつ最も効率的ですか?