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