Why doesn’t the compiler generate compile errors if an incorrect argument type is passed to a struct initialiser list?

A bool can be implicitly converted to an int in a way that’s value preserving. The only disallowed conversions with brace initialization are narrowing conversions (e.g. the reverse bool{42}).

If you want to ensure that your class is constructible only with int, then the direct way is simply to delete all the other constructors:

struct MyStruct
{
    explicit MyStruct(int i) : value(i) { }

    template <typename T>
    MyStruct(T t) = delete;

    int value;
};

Here, MyStruct{true} and MyStruct(false) will yield calls to MyStruct::MyStruct<bool>, which is defined as deleted and hence is ill-formed.

The advantage of this over static_assert is that all the type traits will actually yield the correct values. For instance, std::is_constructible<MyStruct, bool> is std::false_type.

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)