這讓我發瘋。我只想將字串對的可變引數串列發送到替換字串中的單詞的模板函式中,并且該函式可以作業,但只有一個引數,而不是可變引數。
這作業正常
using std::string;
using spair = std::pair<string, string>;
string replace_all(string& str, const spair& sp)
{
string::size_type pos = 0;
string::size_type rmsize = std::get<0>(sp).size();
while((pos = str.find(std::get<0>(sp), pos)) != string::npos)
{
str.replace(pos, rmsize, std::get<1>(sp));
pos ;
}
return str;
}
string pattern = "My name is {{first_name}} {{last_name}} and I live in {{location}}";
string t = replace_all( pattern, {"{{first_name}}","Homer"} );
/*************************/
但這行不通
template<typename T=spair, typename ...Args>
string replace_all(string& s, const T& arg1, Args const&... args )
{
s = replace_all(s, arg1);
s = replace_all(s, args...);
return s;
}
string v = replace_all( pattern,
{"{{first_name}}","Homer"},
{"{{last_name}}","Simpson"},
{"{{location}}","Springfield"}
);
variadic.cpp:72:8: 錯誤:沒有匹配的函式呼叫 **'replace_all(std::string&, <brace-enclosed initializer list>, <brace-enclosed initializer list>, <brace-enclosed initializer list>) '
uj5u.com熱心網友回復:
這里可能存在一些對初始化串列和模板的濫用。總結:
- 內部型別是已知的,它總是一對字串。
- “替換對”的數量應該是可配置的
在這里使用模板,將強制生成新的(函式)型別,無論何時replace_all使用不同數量的對呼叫。如果您像這樣依賴“運行時串列”,則可以大大簡化:
string replace_all(string& s, std::vector<spair> const& v)
{
for (auto const& sp : v) replace_all(s, sp);
return s;
}
// call it like so
replace_all(pattern,
{
{"{{first_name}}","Homer"},
{"{{last_name}}","Simpson"},
{"{{location}}","Springfield"}
}
) << std::endl;
演示
正如@Sam Varshavchik 在評論中提到的那樣,使用您建議的方法進行模式匹配有點問題。如果你像這樣呼叫你的函式,它可以作業:
replace_all(pattern,
spair{"{{first_name}}","Homer"},
spair{"{{last_name}}","Simpson"},
spair{"{{location}}","Springfield"}
);
從而使要推導的型別顯式。
uj5u.com熱心網友回復:
我無法完全理解,但我設計了一個解決方法:
// 1 to 5 replacement pairs
const spair emptyspair{{},{}}; // A "nothing" pair of empty strings
string replace_all(string& s,
const spair& sp1=emptyspair,
const spair& sp2=emptyspair,
const spair& sp3=emptyspair,
const spair& sp4=emptyspair,
const spair& sp5=emptyspair
)
{
std::array<spair,5> v{sp1, sp2, sp3, sp4, sp5};
for (spair sp : v )
{
if (sp != emptyspair)
{
auto& s1 = std::get<0>(sp);
auto& s2 = std::get<1>(sp);
s = replace_all(s, s1, s2);
}
}
return s;
}
這允許 1 到 5 個 spair 引數,默認為一個虛擬對,每個在保存它們的陣列中都被忽略。我認為所有參考都系結到同一個默認物件,因此不會導致創建 10 個字串物件和 5 個對,并且不等式檢查與同一個物件快速比較。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/375297.html
上一篇:輸入引數的型別取決于模板布林值
