问题
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?
回答1:
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";
}
来源:https://stackoverflow.com/questions/42042563/is-it-possible-to-create-a-trait-to-answer-if-a-type-comes-from-std