4

以下

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そして、「大きな」タイプはいつ最も効率的ですか?

4

0 に答える 0