如何解决令人困惑的可变参数模板练习
我给自己设定了这个任务来帮助学习可变参数模板。函数 add_and_cat()
应该首先采用 pair
它似乎在许多情况下都有效,但在其他情况下,我收到一个编译错误,声称没有匹配的函数(在底部)......尽管据我所知似乎只有一个非常明显的候选:/我已经玩过了,并试图推理出来,但......还没有运气。我错过了什么?
--------------------------- 代码:----------- ---------
#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 s) {
store.second += s;
}
//full case for int
template<typename ...Ts>
void add_and_cat(std::pair<int,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 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,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,"B"); pp(p); //fine
//add_and_cat(p,"B"); pp(p); //compile error
//add_and_cat(p,3); pp(p); //compile error
//add_and_cat(p,"B"); pp(p); //fine
//add_and_cat(p,"C"); pp(p); //compile error
//add_and_cat(p,"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*,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,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,int)’
233 | std::pair<int,std::string> add_and_cat(std::pair<int,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::string)’
240 | std::pair<int,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,Ts ...)’
247 | std::pair<int,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...);
| ^~~~
非常感谢您的帮助!
解决方法
当 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,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,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","B"); pp(p); // no compile error
add_and_cat(p,2,3); pp(p); // no compile error
add_and_cat(p,"B","C"); pp(p); // no compile error
add_and_cat(p,"C"); pp(p); // no compile error
}
请注意,您可以使用 fold expression 避免递归:
void add_one(std::pair<int,int x){ store.first -=x; }
void add_one(std::pair<int,const std::string& x){ store.second +=x; }
template <typename ...Ts>
void add_and_cat2(std::pair<int,Ts... t){
(add_one(store,t),...);
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。