当前位置: 首页 > 知识库问答 >
问题:

c字符串模板没有用于调用basic\u字符串的匹配函数

柴深
2023-03-14

我正在编写公共函数以将类型T转换为字符串:

>

当其他人使用stringstream操作符时

当T是std::string时,只需返回T

template <typename Numeric>
string to_str1(Numeric n){
    return std::to_string(n);
}

template <typename NonNumeric>
std::string to_str2(const NonNumeric& v){
    std::stringstream ss;
    ss << v;
    return ss.str();
}

// if T is string just return
std::string to_str2(const std::string& v){
    return v;
}

template<typename T>
string to_str(const T& t){
    if(std::is_integral<T>::value){
        return to_str1(t);
    }else{
        return to_str2(t);
    }
}

测试用法:

int a = 1101;
cout << to_str(a) << endl;

string s = "abc";
cout << to_str(s) << endl;  // should use to_str2(const std::string& v),but compile error

但编译错误:

正在实例化字符串到\u str1。。。。。没有用于调用to\u字符串的匹配函数(std::\u cxx11::basic\u字符串

我不知道为什么会出现这个错误?

共有2个答案

滑畅
2023-03-14

问题是ifore分支都将在编译时进行评估;您可以使用Constexr IF(从C 17开始)。

如果值为true,则放弃语句false(如果存在),否则放弃语句true。

template<typename T>
string to_str(const T& t){
    if constexpr (std::is_integral<T>::value){
        return to_str1(t);
    }else{
        return to_str2(t);
    }
}

或者在SFINAE的帮助下重载to_str

// for integral-numbers
template <typename T>
typename std::enable_if<std::is_integral<T>::value, std::string>::type
to_str(T n){
    return std::to_string(n);
}

// for non-integral-numbers
template <typename T>
typename std::enable_if<!std::is_integral<T>::value, std::string>::type
to_str(const T& v){
    std::stringstream ss;
    ss << v;
    return ss.str();
}

// if T is string just return
std::string to_str(const std::string& v) {
    return v;
}
蔺霄
2023-03-14

当你写作时

if(std::is_integral<T>::value){
    return to_str1(t);
}else{
    return to_str2(t);
}

那么,if条件在运行时总是true或false是正确的,但仍然需要编译这两个分支。但是,第一个分支不适用于t=std::string。

如果要根据编译时常量排除完全编译的分支(语法检查除外),那么可以使用If constexpr:

if constexpr(std::is_integral<T>::value){
    return to_str1(t);
}else{
    return to_str2(t);
}

这告诉编译器在编译时检查if条件,并且只编译将采取的分支。

这需要C 17或更高版本。

 类似资料:
  • 问题 你想要匹配两个或多个字符串。 解决方案 计算把一个字符串转换成另一个字符串所需的编辑距离或操作数。 levenshtein = (str1, str2) -> l1 = str1.length l2 = str2.length prevDist = [0..l2] nextDist = [0..l2] for i in [1..l1] by 1

  • 问题内容: 我需要一个匹配但不匹配的正则表达式 我希望它只匹配foo及其周围的所有内容,只要不跟在bar后面即可。 我尝试使用此方法:这是相当接近的,但它匹配。负面的眼光需要匹配任何东西,而不仅仅是障碍。 我使用的特定语言是Clojure,它在后台使用Java正则表达式。 编辑:更具体地说,我也需要它通过但不是。 问题答案: 尝试: 测试: 正则表达式说明 其他正则表达式 如果您只想排除紧接其后的

  • 问题 你想使用 Unix Shell 中常用的通配符(比如 *.py , Dat[0-9]*.csv 等)去匹配文本字符串 解决方案 fnmatch 模块提供了两个函数—— fnmatch() 和 fnmatchcase() ,可以用来实现这样的匹配。用法如下: >>> from fnmatch import fnmatch, fnmatchcase >>> fnmatch('foo.txt',

  • 问题内容: 是否可以将模板字符串创建为常规字符串 然后将其转换为模板字符串 没有,以及其他动态代码生成方式? 问题答案: 由于您的模板字符串必须动态地(在运行时)引用该变量,因此答案是: 否,没有动态代码生成是不可能的。 但这很简单:

  • ES6引入了一种通过反引号( ` )标记的新的字符串文字类型。 这些字符串文字可以包括换行符,并且有一个新的机制用于将变量插入字符串:

  • 下面就是Array#pack、String#unpack中所用到的模板字符的一览表。模板字符后面可以跟上表示"长度"的数字。若使用'*'来取代"长度"的话, 则表示"剩下的所有字符"之意。 长度的定义因模板字符的不同而有所差异, 大体上像 "iiii" 这样的连续字符可以写成 "i4" 这个样子。 在下面的说明中, short和long分别表示长度为2和4字节的数值(也就是通常32位机器所指的