字符串的类型特征

Posted

技术标签:

【中文标题】字符串的类型特征【英文标题】:Type trait for strings 【发布时间】:2011-11-11 17:13:19 【问题描述】:

是否存在(在标准库或 Boost 中)类型特征来测试类型是否可以表示字符串?

我在使用 Boost.Fusion 时偶然发现了一个问题:

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

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

我希望filter 会保留“one”,但它失败了,因为“one”没有衰减为指针(make_vector 通过引用获取其参数,因此类型为const char (&amp;)[4])。因此,我需要一个能让我写出这样的特性:

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

我知道char const *const char[N] 不一定是以空值结尾的字符串,但能够统一检测它们仍然很方便。该特征也可能返回 truestd::string 等。

这样的特征是否存在,还是我必须自己写?

【问题讨论】:

static_cast&lt;const char *&gt;("one") 怎么样?还是一个接受数组并将它们转换为指针的通用模板? @KerrekSB:在函数调用中封装每个字符串文字似乎是一个真正的负担,但特征可以使用函数模板来测试类型是否可以转换为 char 指针...... 仅供参考,您在 assert() 中缺少一个结束卡伦。 @semisight:谢谢,已更正。 我刚刚意识到,如果is_string&lt;std::string&gt;::value 为真,那么您转换为const char* 将不起作用,对吗? (他们是否在 C++11 中添加了显式转换?) 【参考方案1】:

我尝试过实现这样的特性,但我不确定它是否真的很健壮。任何意见将不胜感激。

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 ;

【讨论】:

or_ 不包括在 11 中,没有。我相信,等价的应该是std::integral_constant&lt;bool, std::is_same&lt;...&gt;::value || std::is_same&lt;...&gt;::value&gt; or 包含在 C++17 库中。请参阅 std::disjunction 并注意这是 short-circuiting 特征。【参考方案2】:

这应该适用于 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<T>>,
                std::is_same<const char *, typename std::decay_t<T>>,
                std::is_same<std::string, typename std::decay_t<T>>
        > 
;

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"

【讨论】:

以上是关于字符串的类型特征的主要内容,如果未能解决你的问题,请参考以下文章

变量类型|数据类型|统计特征|

re 库

scikit-learn 中的逻辑回归特征值归一化

将特征矩阵转换为无符号字符 *

PHP加密后门特征,如何找出后门?

基于特征匹配的英文印刷字符识别matlab源码