I'm writing a function that can pour the content of a string vector into variables. Here's what it looks like:
#include <iostream>
#include <string>
#include <sstream>
#include <vector>
template <typename T, int N = 0>
void pour2(std::vector<std::string> const& vals, T& val) {
std::stringstream ss;
ss << vals[N];
ss >> val;
}
template <typename T, typename ...Ts, int N = 0>
void pour2(std::vector<std::string> const& vals, T& val, Ts& ...args) {
std::stringstream ss;
ss << vals[N];
ss >> val;
pour2<Ts..., N+1>(vals, args...);
}
int main() {
std::vector<std::string> info = {"3", "1.5", "/home/tq/playground/"};
int sz;
double val;
std::string dir;
pour2(info, sz, val, dir);
std::cout << "size = " << sz << std::endl;
std::cout << "value = " << val << std::endl;
std::cout << "dir = " << dir << std::endl;
return 0;
}
However, g++-9.2 complains that
test.cpp: In instantiation of ‘void pour2(const std::vector<std::__cxx11::basic_string<char> >&, T&, Ts& ...) [with T = int; Ts = {double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >}; int N = 0]’:
test.cpp:30:26: required from here
test.cpp:18:19: error: no matching function for call to ‘pour2<double, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, (0 + 1)>(const std::vector<std::__cxx11::basic_string<char> >&, double&, std::__cxx11::basic_string<char>&)’
18 | pour2<Ts..., N+1>(vals, args...);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
test.cpp:7:6: note: candidate: ‘template<class T, int N> void pour2(const std::vector<std::__cxx11::basic_string<char> >&, T&)’
7 | void pour2(std::vector<std::string> const& vals, T& val) {
| ^~~~~
test.cpp:7:6: note: template argument deduction/substitution failed:
test.cpp:18:19: error: wrong number of template arguments (3, should be at least 1)
18 | pour2<Ts..., N+1>(vals, args...);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~
test.cpp:14:6: note: candidate: ‘template<class T, class ... Ts, int N> void pour2(const std::vector<std::__cxx11::basic_string<char> >&, T&, Ts& ...)’
14 | void pour2(std::vector<std::string> const& vals, T& val, Ts& ...args) {
| ^~~~~
test.cpp:14:6: note: template argument deduction/substitution failed:
and clang-9.0.1 says
test.cpp:18:2: error: no matching function for call to 'pour2'
pour2<Ts..., N+1>(vals, args...);
^~~~~~~~~~~~~~~~~
test.cpp:30:2: note: in instantiation of function template specialization 'pour2<int, double, std::__cxx11::basic_string<char> , 0>' requested here
pour2(info, sz, val, dir);
^
test.cpp:14:6: note: candidate template ignored: invalid explicitly-specified argument for template parameter 'Ts'
void pour2(std::vector<std::string> const& vals, T& val, Ts& ...args) {
^
test.cpp:7:6: note: candidate function template not viable: requires 2 arguments, but 3 were provided
void pour2(std::vector<std::string> const& vals, T& val) {
^
1 error generated.
I find that if I move the non-type template parameter to be the first argument, the code can compile and work as expected:
template <int N = 0, typename T>
void pour(std::vector<std::string> const& vals, T& val) {
std::stringstream ss;
ss << vals[N];
ss >> val;
}
template <int N = 0, typename T, typename ...Ts>
void pour(std::vector<std::string> const& vals, T& val, Ts& ...args) {
std::stringstream ss;
ss << vals[N];
ss >> val;
pour<N+1, Ts...>(vals, args...);
}
I just wonder, why it doesn't work in the first case?
Aucun commentaire:
Enregistrer un commentaire