使用一点 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> {};