lundi 28 décembre 2015

Bug in MSVC compiler? Clang and GCC don't complain. Testing for valid operator in compile time

So consider the following:

Used for convenience (plus C++17 "support"):

template<typename...>
using void_t = void;

template<bool B>
using bool_constant = std::integral_constant<bool, B>;

Then we have the main stuff:

//is_post_incrementable
template<typename, typename = void_t<>>
struct is_post_incrementable : std::false_type {};

template<typename T>
struct is_post_incrementable<T, void_t<decltype(std::declval<T&>()++)>> : std::true_type {};

//is_pre_incrementable
template<typename, typename = void_t<>>
struct is_pre_incrementable : std::false_type {};

template<typename T>
struct is_pre_incrementable<T, void_t<decltype(++std::declval<T&>())>> : std::true_type {};

//is_incrementable
template<typename T>
struct is_incrementable : bool_constant<is_pre_incrementable<T>::value
                                     || is_post_incrementable<T>::value> {};

We apply some tests on:

struct foo { int a = 2; };
struct foo2 { int a = 2; foo2& operator++() { ++a; return *this; } };
struct foo3 { int a = 2; foo3 operator++(int) { foo3 temp(*this); ++a; return *this; } };

int main()
{
    std::cout << is_pre_incrementable<foo>::value; //0
    std::cout << is_pre_incrementable<foo2>::value; //0 - should be 1
    std::cout << is_pre_incrementable<foo3>::value; //1 - should be 0
    std::cout << "\n";
    std::cout << is_post_incrementable<foo>::value; //0
    std::cout << is_post_incrementable<foo2>::value; //0
    std::cout << is_post_incrementable<foo3>::value; //1
    std::cout << "\n";
    std::cout << is_incrementable<foo>::value; //0
    std::cout << is_incrementable<foo2>::value; //0 - should be 1
    std::cout << is_incrementable<foo3>::value; //1
}

Those are the results I get in MVSC. The weird thing is this: If I move is_pre_increment over is_post_increment in the code, instead of 001 001 001, I get 010 010 010. It still isn't the desired 010 001 011 result.

Clang and GCC produce the expected result though.

LIVE example(Clang): http://ift.tt/1JcgI8U

LIVE example(GCC): http://ift.tt/1ko3ZEs

Is there a logic error on my part, or is it a plain MSVC bug?

Aucun commentaire:

Enregistrer un commentaire