W.F. W.F. - 4 years ago 120
C++ Question

Is it possible to create a trait to answer if a type comes from std?

After this question by utilizing ADL one can create a trait to answer if the passed type comes from our namespace:

#include <utility>

namespace helper
{
template <typename T, typename = void>
struct is_member_of_sample : std::false_type
{
};

template <typename T>
struct is_member_of_sample<
T,
decltype(adl_is_member_of_sample(std::declval<T>()))> : std::true_type
{
};
}

namespace sample
{
template <typename T>
auto adl_is_member_of_sample(T && ) -> void;
}

// -- Test it

namespace sample
{
struct X;
}

struct Y;

static_assert(helper::is_member_of_sample<sample::X>::value, "");
static_assert(not helper::is_member_of_sample<Y>::value, "");

int main(){}


From obvious reason this cannot be applied to the
std
namespace - there is simply no way to inject the
adl_is_member_of_sample
equivalent to the
std
namespace without exposing ourself to undefined behaviour.

Is there some workaround enabling to create the trait?

Answer Source

This seems to work:

#include <functional>
#include <type_traits>
#include <utility>
#include <string>

namespace other { struct S{}; }

namespace my {
    template< class Type >
    void ref( Type&& ) {}

    template< class Type >
    auto ref_to( Type&& o )
        -> Type&
    { return o; }

    template< class Type >
    constexpr auto is_std_type()
        -> bool
    {
        using std::is_same;
        using std::declval;
        return not is_same< void, decltype( ref( ref_to( declval<Type>() ) ) )>::value;
    }

    struct Blah {};

    constexpr bool int_is_std       = is_std_type<int>();
    constexpr bool blah_is_std      = is_std_type<Blah>();
    constexpr bool other_is_std     = is_std_type<other::S>();
    constexpr bool string_is_std    = is_std_type<std::string>();
};

#include <iostream>
using namespace std;
auto main()
    -> int
{
    cout << boolalpha;
    cout << "int is std = " << my::int_is_std << "\n";
    cout << "blah is std = " << my::blah_is_std << "\n";
    cout << "other is std = " << my::other_is_std << "\n";
    cout << "string is std = " << my::string_is_std << "\n";
}
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download