3

いくつかの縮小変換を示す次のコードを検討してください。

template <class T>
class wrapper 
{   
    template <class> friend class wrapper;
    public:
        constexpr wrapper(T value)
        : _data(value)
        {}
        template <class U>
        constexpr wrapper(wrapper<U> other)
        : _data(other._data) 
        {}
        wrapper& operator=(T value)
        {_data = value; return *this;}
        template <class U>
        wrapper& operator=(wrapper<U> other)
        {_data = other._data; return *this;}
    private:
        T _data;
};

int main(int argc, char* argv[]) 
{
    wrapper<unsigned char> wrapper1 = 5U;
    wrapper<unsigned char> wrapper2{5U};
    wrapper<unsigned char> wrapper3(5U);
    wrapper<unsigned int> wrapper4 = 5U;
    wrapper<unsigned int> wrapper5{5U};
    wrapper<unsigned int> wrapper6(5U);
    wrapper<unsigned char> wrapper7 = wrapper4;  // Narrowing
    wrapper<unsigned char> wrapper8{wrapper5};  // Narrowing
    wrapper<unsigned char> wrapper9(wrapper6);  // Narrowing
    wrapper7 = wrapper4;  // Narrowing
    wrapper8 = wrapper5;  // Narrowing
    wrapper9 = wrapper6;  // Narrowing
    return 0;
}

メンバーの本体を変更して、wrapper変換を縮小するためのコンパイラ警告をトリガーする方法は? 私の目標は、コードに問題がある可能性があることをユーザーに認識させることです。

4

3 に答える 3

3

絞り込み呼び出しでコンパイルを停止するには、SFINAE を使用できます

template <class U>
constexpr wrapper(wrapper<U> other)
: _data(other._data) 
{}

そして、それをに変更します

template <class U, typename std::enable_if<sizeof(T) >= sizeof(U)>::type* = nullptr>
constexpr wrapper(wrapper<U> other)
: _data(other._data) 
{}

Live Example

コピー元の基になる型のサイズが、初期化するオブジェクトの基になる型よりも大きい場合、これによりコンパイルが停止します。

于 2016-10-12T21:27:25.943 に答える
0

別の方法をお勧めします。コードをいじる必要はありません。g++ を使用してコンパイルする場合は、-Wconversion フラグを追加します。

于 2016-10-12T21:27:13.913 に答える