I am trying to create a function that works with a template that is supposed to adapt to a container with a vector
class by itself as default. T<int>
for example. However, when I try to use this function in main
I get the error that there is no matching function.
#include<string>
#include<iostream>
#include<fstream>
#include<vector>
#include<list>
#include<deque>
#include<forward_list>
using namespace std;
template<template <typename> class Container = vector>
Container<string> filter_codes(const string& route, const char& init) {
Container<string> _return;
vector<string> temp;
ifstream file(route);
string wd;
while(file>>wd){
if(wd[0]==init)
temp.push_back(wd);
}
_return.resize(temp.size());
copy(temp.begin(), temp.end(), begin(_return));
file.close();
return _return;
}
int main(){
vector<string> code = filter_codes("a.txt", 'c');
for(auto i : code) cout<<i<<' ';
return 0;
}
The error is
main.cpp:36:24: error: no matching function for call to 'filter_codes'
vector<string> code = filter_codes("a.txt", 'c');
^~~~~~~~~~~~
main.cpp:14:19: note: candidate template ignored: substitution failure :
template template argument has different template parameters than its
corresponding template template parameter
Container<string> filter_codes(const string& route, const char& init)
I'm planning to use the function through the following statements.
vector<string> t1 = filter_codes("a.txt", 'x');
auto t2 = filter_codes<list>("a.txt", 'x');
CodePudding user response:
Your code is valid, and is compiled by GCC and MSVC. However, a Clang bug means the template type you use needs to match exactly with the template template parameter. Since std::vector
has 2 template parameters, and the template template parameter you've written has only 1, it's not an exact match and it fails, even though it's at least as specialized, and is valid.
To get this to work on Clang, change your template template parameter to be templated on a variadic number of template parameters
template<template <typename ...> class Container = vector>
// ^^^
Container<string> filter_codes(const string& route, const char& init) {
// ...
}
This works everywhere.