在使用ADL this question之后,如果传递的类型来自我们的命名空间,可以创建一个特征来回答:
#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(){}
由于显而易见的原因,这不能应用于std
命名空间 - 根本没有办法将adl_is_member_of_sample
等价物注入std
命名空间而不将自己暴露给未定义的行为。
是否有一些解决方法可以创建特征?
答案 0 :(得分:5)
这似乎有效:
#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";
}