Type trait for strings

你说的曾经没有我的故事 提交于 2019-12-07 14:20:12

问题


Is there an existing (in the standard library or in Boost) type trait to test whether a type could represent a string?

I stumbled upon an issue when using Boost.Fusion:

auto number = fusion::make_vector( 1, "one" );
auto numberName = fusion::filter< char const * >( number );

assert( numberName == fusion::make_vector( "one" ) ); // fails

I hoped filter would retain "one", but it failed because "one" is not decayed to a pointer (make_vector takes its arguments by reference, so the type is const char (&)[4]). Consequently, I need a trait that would allow me to write something like this:

auto numberName = fusion::filter_if< is_string< mpl::_ > >( number );

I am aware that a char const * and a const char[N] are not necessarily null-terminated strings, but it would still be handy to be able to detect them uniformly. The trait could also possibly return true for std::string and the likes.

Does such a trait exist or will I have to write my own?


回答1:


I gave a shot at implementing such a trait, but I am not sure it is really robust. Any input will be appreciated.

template <typename T>
struct is_string
    : public mpl::or_< // is "or_" included in the C++11 library?
        std::is_same<       char *, typename std::decay< T >::type >,
        std::is_same< const char *, typename std::decay< T >::type >
     > {};

assert ( ! is_string< int >::value );

assert (   is_string< char       *       >::value );
assert (   is_string< char const *       >::value );
assert (   is_string< char       * const >::value );
assert (   is_string< char const * const >::value );

assert (   is_string< char       (&)[5] >::value );
assert (   is_string< char const (&)[5] >::value );

// We could add specializations for string classes, e.g.
template <>
struct is_string<std::string> : std::true_type {};



回答2:


This should work in C++17.

#include <iostream>
#include <string>
#include <type_traits>

template<typename T>
struct is_string
        : public std::disjunction<
                std::is_same<char *, typename std::decay<T>::type>,
                std::is_same<const char *, typename std::decay<T>::type>,
                std::is_same<std::string, typename std::decay<T>::type>
        > {
};

int main()
{
    std::cout << std::boolalpha;
    std::string str = "i am a string";
    std::cout << is_string<decltype(str)>::value << std::endl; // "true"
    std::cout << is_string<decltype("i am a string literal")>::value << std::endl; // "true"
}


来源:https://stackoverflow.com/questions/8097534/type-trait-for-strings

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!