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 に答える