如果类型来自 std,是否可以创建一个特征来回答?
Is it possible to create a trait to answer if a type comes from std?
在 之后,通过使用 ADL 可以创建一个特征来回答传递的类型是否来自我们的命名空间:
#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
命名空间 - 根本没有办法在不暴露自己未定义行为的情况下注入等同于 std
命名空间的 adl_is_member_of_sample
。
是否有一些解决方法可以创建特征?
这似乎有效:
#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";
}
在
#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
命名空间 - 根本没有办法在不暴露自己未定义行为的情况下注入等同于 std
命名空间的 adl_is_member_of_sample
。
是否有一些解决方法可以创建特征?
这似乎有效:
#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";
}