我编写了以下代码来确定类型是否是std::basic_string
的实例化:
template <typename T>
struct is_string
{
enum { value = false };
};
template <typename charT, typename traits, typename Alloc>
struct is_string<std::basic_string<charT, traits, Alloc> >
{
enum { value = true };
};
有没有更简洁的方法来实现这一目标?
答案 0 :(得分:2)
好的,我找到了一个稍微短的方式:
#include <type_traits>
template <typename T>
struct is_string : std::false_type {};
template <typename charT, typename traits, typename Alloc>
struct is_string<std::basic_string<charT, traits, Alloc> > : std::true_type {};
但也许其他人可以做得更好? :)
答案 1 :(得分:0)
使用一点SFINAE,甚至可以检查该类型是否来自某些basic_string:
#include <type_traits>
namespace detail
{
template <typename T, class Enable = void>
struct is_string : std::false_type {};
template <typename... T>
struct void_helper { typedef void type; };
template <typename T>
struct is_string<T,
typename void_helper<
typename T::value_type,
typename T::traits_type,
typename T::allocator_type
>::type
>
: std::is_base_of<
std::basic_string<
typename T::value_type,
typename T::traits_type,
typename T::allocator_type
>,
T
>
{};
}
template <typename T>
struct is_string : detail::is_string<T> {};
答案 2 :(得分:0)
另一种方法不是那么简洁,因为你的解决方案我承认:-),但是也检测从basic_string派生的类和指向字符串的指针将是:
namespace string_traits
{
typedef char yes_type;
struct no_type
{
char padding[8];
};
no_type string_helper(...);
template <typename charT, typename traits, typename Alloc>
yes_type string_helper(std::basic_string<charT, traits, Alloc>);
template <typename T>
typename std::remove_pointer<T>::type MakeT();
template <typename T>
struct is_string : std::integral_constant<bool,sizeof(string_helper(MakeT<T>()))==sizeof(yes_type)> {};
template <> struct is_string<void> : std::false_type { };
}
class TestString : public std::basic_string<char> { };
class A { };
template <bool b>
void check()
{
cout << (b?"Is string":"Is not string") << endl;
}
int main()
{
using namespace string_traits;
//not strings
check<is_string<void>::value>();
check<is_string<int>::value>();
check<is_string<int(&)[2]>::value>();
check<is_string<string(&)[2]>::value>();
check<is_string<string**>::value>();
check<is_string<A>::value>();
//strings
check<is_string<string>::value>();
check<is_string<TestString>::value>();
check<is_string<TestString&>::value>();
check<is_string<TestString*>::value>();
check<is_string<std::wstring>::value>();
check<is_string<string*>::value>();
check<is_string<string&>::value>();
}