Want to write a CanCout SFINAE helper.

Want to write a CanCout SFINAE helper. MSVC is very easy to do (as always the case), but G++ is a different story. Current attempt:

1
2
3
4
5
6
7
8
9
10
template<typename T>
class CanCout
{
    template<typename = decltype(std::cout << std::declval<T>())>
    static constexpr bool test(int) { return true; }

    static constexpr bool test(...) { return false; }
public:
    constexpr static bool value = test(int());
};


interestingly g++ is happy with this though:

1
2
3
4
5
6
7
8
9
10
template<typename T>
class CanDivideByInt
{
    template<typename = decltype(std::declval<T>() /= int())>
    static constexpr bool test(int) { return true; }

    static constexpr bool test(...) { return false; }
public:
    constexpr static bool value = test(int());
};


Same pattern more or less.
Last edited on
ok found the answer here: https://stackoverflow.com/questions/22758291/how-can-i-detect-if-a-type-can-be-streamed-to-an-stdostream

This code is all good:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename S, typename T>
class is_streamable
{
    template<typename SS, typename TT>
    static constexpr decltype( std::declval<SS&>() << std::declval<TT>(), bool() ) test(int) { return true; };

    template<typename...> static constexpr auto test(...) { return false; }

public:
    static constexpr bool value = test<S,T>(int());
};

template<typename T>
using CanCout = is_streamable<std::decay_t<decltype(std::cout)>, T>;


Or maybe not. std::cout is not an rvalue reference after all. Weird... So I got something that works, but still not sure why that's the case.
Last edited on
Topic archived. No new replies allowed.