C++ 令人困惑的可变模板练习
我给自己设置这个任务是为了帮助学习可变模板。函数C++ 令人困惑的可变模板练习,c++,function,c++11,variadic-templates,C++,Function,C++11,Variadic Templates,我给自己设置这个任务是为了帮助学习可变模板。函数add_and_cat()应首先获取一对,然后获取可变数量的整数或字符串或混合数。当它递归地遇到这些问题时,它应该从pair.first中减去每个int,并将每个字符串连接到pair.second上。函数pp只打印这一对 它在很多情况下似乎都能工作,但在其他情况下,我会得到一个编译错误,声称没有匹配的函数(在底部)。。。尽管就我所知,似乎只有一个非常明显的候选人:/我一直在玩弄,试图找出原因,但。。。还没有运气。我错过了什么 -----------
add_and_cat()
应首先获取一对,然后获取可变数量的整数或字符串或混合数。当它递归地遇到这些问题时,它应该从pair.first中减去每个int,并将每个字符串连接到pair.second上。函数pp只打印这一对
它在很多情况下似乎都能工作,但在其他情况下,我会得到一个编译错误,声称没有匹配的函数(在底部)。。。尽管就我所知,似乎只有一个非常明显的候选人:/我一直在玩弄,试图找出原因,但。。。还没有运气。我错过了什么
--------------------------代码:----------------------------
#include <iostream>
void pp(std::pair<int,std::string> printme) {
std::cout << printme.first << " : " << printme.second << "\n";
}
//base case int
//must be int or std::string for now
void add_and_cat(std::pair<int, std::string>& store, int i) {
store.first -= i;
}
//base case string
void add_and_cat(std::pair<int, std::string>& store, std::string s) {
store.second += s;
}
//full case for int
template<typename ...Ts>
void add_and_cat(std::pair<int, std::string>& store, int i, Ts... rest) {
store.first -= i;
add_and_cat(store, rest...);
}
//full case for string
template<typename ...Ts>
void add_and_cat(std::pair<int, std::string>& store, std::string s, Ts... rest) {
store.second += s;
add_and_cat(store, rest...);
}
int main()
{
std::pair<int, std::string> p{0,"START"};
//add_and_cat(p, 1, 2, 3, 4); pp(p); //fine
//add_and_cat(p, 3, 4, 5, 6); pp(p); //fine
//add_and_cat(p, "A", "B", "C", "D"); pp(p); //fine
//add_and_cat(p, "D", "E", "F", "G"); pp(p); //fine
//add_and_cat(p, "A", 1, "B"); pp(p); //fine
//add_and_cat(p, 1, "A", 1, "B"); pp(p); //compile error
//add_and_cat(p, 1, 2, "A",3); pp(p); //compile error
//add_and_cat(p, "A", 1, 2, "B"); pp(p); //fine
//add_and_cat(p, "A", 1, 2, "B","C"); pp(p); //compile error
//add_and_cat(p, 1, 2, "B","C"); pp(p); //compile error
return 0;
}
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp: In instantiation of ‘std::pair<int, std::__cxx11::basic_string<char> > add_and_cat(std::pair<int, std::__cxx11::basic_string<char> >&, int, Ts ...) [with Ts = {const char*, int, const char*}]’:
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:273:45: required from here
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:250:20: error: no matching function for call to ‘add_and_cat(std::pair<int, std::__cxx11::basic_string<char> >&, const char*&, int&, const char*&)’
250 | return add_and_cat(store, rest...);
| ~~~~~~~~~~~^~~~~~~~~~~~~~~~
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:233:29: note: candidate: ‘std::pair<int, std::__cxx11::basic_string<char> > add_and_cat(std::pair<int, std::__cxx11::basic_string<char> >&, int)’
233 | std::pair<int, std::string> add_and_cat(std::pair<int, std::string>& store, int i) {
| ^~~~~~~~~~~
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:233:29: note: candidate expects 2 arguments, 4 provided
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:240:29: note: candidate: ‘std::pair<int, std::__cxx11::basic_string<char> > add_and_cat(std::pair<int, std::__cxx11::basic_string<char> >&, std::string)’
240 | std::pair<int, std::string> add_and_cat(std::pair<int, std::string>& store, std::string s) {
| ^~~~~~~~~~~
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:240:29: note: candidate expects 2 arguments, 4 provided
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:247:29: note: candidate: ‘template<class ... Ts> std::pair<int, std::__cxx11::basic_string<char> > add_and_cat(std::pair<int, std::__cxx11::basic_string<char> >&, int, Ts ...)’
247 | std::pair<int, std::string> add_and_cat(std::pair<int, std::string>& store, int i, Ts... rest) {
| ^~~~~~~~~~~
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:247:29: note: template argument deduction/substitution failed:
/mnt/c/Users/Tim/Nextcloud/playground/seqan3/source/hello_world.cpp:250:28: note: cannot convert ‘rest#0’ (type ‘const char*’) to type ‘int’
250 | return add_and_cat(store, rest...);
| ^~~~
#包括
无效pp(标准::成对打印){
std::cout当int
重载必须调用string
重载时,即当int
参数在string
前面时,它会失败。在调用该函数之前,必须先声明该函数:
#include <iostream>
//...
// declare "full case for string" called in "full case for int"
template<typename ...Ts>
void add_and_cat(std::pair<int, std::string>& store, std::string s, Ts... rest);
//full case for int
template<typename ...Ts>
void add_and_cat(std::pair<int, std::string>& store, int i, Ts... rest) {
store.first -= i;
add_and_cat(store, rest...);
}
//full case for string
template<typename ...Ts>
void add_and_cat(std::pair<int, std::string>& store, std::string s, Ts... rest) {
store.second += s;
add_and_cat(store, rest...);
}
int main()
{
std::pair<int, std::string> p{0,"START"};
add_and_cat(p, 1, "A", 1, "B"); pp(p); // no compile error
add_and_cat(p, 1, 2, "A",3); pp(p); // no compile error
add_and_cat(p, "A", 1, 2, "B","C"); pp(p); // no compile error
add_and_cat(p, 1, 2, "B","C"); pp(p); // no compile error
}
#包括
//...
//声明“整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型整型
模板
void add_和_cat(std::pair&store,std::string s,Ts…rest);
//int的完整情况
模板
void add_和_cat(std::pair&store、int i、Ts…rest){
store.first-=i;
添加_和_cat(商店、休息…);
}
//字符串的完整大小写
模板
void add_和_cat(std::pair&store,std::string s,Ts…rest){
store.second+=s;
添加_和_cat(商店、休息…);
}
int main()
{
std::对p{0,“START”};
添加_和_cat(p,1,“A”,1,“B”);pp(p);//无编译错误
添加_和_cat(p,1,2,“A”,3);pp(p);//无编译错误
添加_和_cat(p,“A”,1,2,“B”,“C”);pp(p);//无编译错误
添加_和_cat(p,1,2,“B”,“C”);pp(p);//无编译错误
}
请注意,可以使用以下方法避免递归:
void add_one(std::pair&store,intx){store.first-=x;}
void add_one(std::pair&store,const std::string&x){store.second+=x;}
模板
无效添加_和_cat2(标准::配对和存储,Ts…t){
(增加一个(商店,t),…);
}
我需要为其中一个函数添加一个正向声明,但它对我来说很有用:
void add_one(std::pair<int,std::string>& store,int x){ store.first -=x; }
void add_one(std::pair<int,std::string>& store,const std::string& x){ store.second +=x; }
template <typename ...Ts>
void add_and_cat2(std::pair<int,std::string>& store,Ts... t){
(add_one(store,t),...);
}