c++ 字符串模板没有匹配函数来调用 basic_string<char>
c++ string template no matching function for call to basic_string<char>
我正在编写将类型 T 转换为字符串的通用函数:
当T是数字类型时就用std::to_string
当别人使用stringstream操作符时<<
当 T 是 std::string 只是 return 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
但是编译错误:
在字符串实例化中 to_str1 ..... 没有匹配函数调用 to_string(std::__cxx11::basic_string
我不知道为什么会出现这个错误,?
写的时候
if(std::is_integral<T>::value){
return to_str1(t);
}else{
return to_str2(t);
}
那么确实if
条件在运行时要么一直为真,要么一直为假,但是还是要求两个分支都能编译通过。然而,第一个分支不适用于 T = std::string
.
如果你想根据编译时间常数完全排除分支编译(除了语法检查),那么你可以使用 if constexpr
:
if constexpr(std::is_integral<T>::value){
return to_str1(t);
}else{
return to_str2(t);
}
这告诉编译器在编译时检查 if
条件,并且只编译将采用的分支。
这需要 C++17 或更高版本。
问题是 if
和 else
分支都将在编译时求值;你可以使用 Constexpr If (C++17 起).
If the value is true
, then statement-false is discarded (if present), otherwise, statement-true is discarded.
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;
}
我正在编写将类型 T 转换为字符串的通用函数:
当T是数字类型时就用std::to_string
当别人使用stringstream操作符时<<
当 T 是 std::string 只是 return 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
但是编译错误:
在字符串实例化中 to_str1 ..... 没有匹配函数调用 to_string(std::__cxx11::basic_string
我不知道为什么会出现这个错误,?
写的时候
if(std::is_integral<T>::value){
return to_str1(t);
}else{
return to_str2(t);
}
那么确实if
条件在运行时要么一直为真,要么一直为假,但是还是要求两个分支都能编译通过。然而,第一个分支不适用于 T = std::string
.
如果你想根据编译时间常数完全排除分支编译(除了语法检查),那么你可以使用 if constexpr
:
if constexpr(std::is_integral<T>::value){
return to_str1(t);
}else{
return to_str2(t);
}
这告诉编译器在编译时检查 if
条件,并且只编译将采用的分支。
这需要 C++17 或更高版本。
问题是 if
和 else
分支都将在编译时求值;你可以使用 Constexpr If (C++17 起).
If the value is
true
, then statement-false is discarded (if present), otherwise, statement-true is discarded.
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;
}