【问题标题】:Template excluding one type不包括一种类型的模板
【发布时间】:2012-09-29 07:11:09
【问题描述】:

我想做一个不包括类型字符串或字符的解析函数

template <typename T>
bool parse(T & value, const string & token){
    istringstream sin(token);
    T t;
    if( !(sin >>t) )  return false;
    char junk;
    if( sin >>junk )  return false;
    value = t;
    return true;
}

我该怎么做?

【问题讨论】:

  • 为什么?为什么不直接将其称为字符串或字符...更容易。
  • 您希望字符串和字符发生什么?那么 char 指针和数组呢?
  • 我正在接受一个输入,它应该有一个数字序列 1st 我存储在一个数组中。然后,理想情况下,数字后面应该有字符。我需要将数字解析为正确的类型,然后将它们存储到我在其他地方的模板数组中。

标签: c++ string templates types char


【解决方案1】:

您可以使用增强型特征。他们有一个名为 is_same 的类型比较检查

http://www.boost.org/doc/libs/1_51_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html

你可以只用比较的结果到 char 和 string。

【讨论】:

    【解决方案2】:

    根据您的意思排除类型stringchar。如果您不希望它链接,您可以声明但不定义类型的特化:

    template <>
    void parse<std::string>( std::string & value, const std::string& token );
    

    编译器将看到特化而不生成代码。链接器将失败,因为该符号未在任何翻译单元中定义。

    第二种方法更复杂一点,不是在链接时失败,而是让编译器不接受那些类型的模板。这可以通过 SFINAE 完成,它在 C++11 中更简单,但如果您需要 C++03 解决方案,您可以 google 或添加评论:

    template <typename T, 
              typename = typename std::enable_if<!std::is_same<T,std::string>
                                              && !std::is_same<T,char>>::type >
    void parse( T & t, const std::string& token ) {
    // ...
    }
    

    (我没有通过编译器运行它,所以语法可能有点不对,玩吧)编译器会看到模板,当它尝试执行T类型的替换时,它会失败std::enable_if&lt;...&gt;::type 没有解析为类型。

    一般来说,您可能想要的是提供不同的重载来执行特定版本的parse 并优先:

    void parse( std::string& v, const std::string& token ) {
        v = token;
    }
    

    请注意,这不是模板,而是常规函数。当调用的参数完全匹配时,非模板函数将比模板函数更好地匹配。

    【讨论】:

    • 您的建议有效。我想我会使用重载函数。这是一个更容易阅读的解决方案。
    【解决方案3】:

    模板应该这样声明 David Rodríguez 的方法(用于返回类型的函数):

    template <template T, typename std::enable_if<!std::is_same<T,std::string>::value>::type* = nullptr >
    T func(T x){}
    

    对于多个条件:

    template <template T, typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type* = nullptr >
    T func(T x){}
    

    对于没有返回类型的函数:

    template <template T>
    typename std::enable_if<!std::is_same<T,std::string>::value>::type
    func(T x){}
    

    对于多个条件:

    template <template T>
    typename std::enable_if<!std::is_same<T,std::string>::value &&!std::is_same<T,int>::value>::type
    func(T x){}
    

    不要忘记包含#include &lt;type_traits&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-05-07
      • 2021-06-10
      • 1970-01-01
      • 2018-05-09
      • 2016-08-07
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多