我正在撰寫將型別 T 轉換為字串的通用函式:
當 T 是數字型別時,只需使用 std::to_string
當其他人使用 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
但編譯錯誤:
在字串 to_str1 的實體化中 ..... 沒有匹配的函式呼叫 to_string(std::__cxx11::basic_string
我不知道為什么這個錯誤,?
uj5u.com熱心網友回復:
當你寫
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 或更高版本。
uj5u.com熱心網友回復:
問題是 theif和elsebranch 都會在編譯時被評估;您可以使用Constexpr If (C 17 起)。
如果值為
true,則丟棄statement-false(如果存在),否則丟棄statement-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);
}
}
或者to_str在SFINAE的幫助下超載。
// 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;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/402182.html
上一篇:具有多個定義的C 11模板類
