5

我编写了以下代码来确定类型是否是 的实例化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 };
};

有没有更简洁的方法来实现这一目标?

4

3 回答 3

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 {};

但也许其他人可以做得更好?:)

于 2011-02-25T11:55:08.650 回答
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> {};
于 2011-02-23T19:19:30.120 回答
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>();
}
于 2011-02-24T09:42:50.803 回答