我有这个测试程序
#include<iostream>
#include<vector>
using namespace std;
template<template<class> class C, typename T>
void print(const C<T>& c){
for(auto& e : c)cout<<e<<endl;
}
int main(){
vector<int> v;
print(v);
return 0;
}
它无法编译:
g++ m.cpp -std=c++11
m.cpp: In function ‘int main()’:
m.cpp:11:16: error: no matching function for call to ‘print(std::vector<int>&)’
print(v);
^
m.cpp:6:6: note: candidate: template<template<class> class C, class T> void print(const C<T>&)
void print(const C<T>& c){
^~~~~
m.cpp:6:6: note: template argument deduction/substitution failed:
m.cpp:11:16: note: template parameters of a template template argument are inconsistent with other deduced template arguments
print(v);
^
我将print()签名从(const C& c)更改为(C& c),它仍然失败:
$g++ m.cpp -std=c++11
m.cpp: In function ‘int main()’:
m.cpp:11:16: error: no matching function for call to ‘print(std::vector<int>&)’
print(v);
^
m.cpp:6:6: note: candidate: template<template<class> class C, class T> void print(C<T>&)
void print(C<T>& c){
^~~~~
m.cpp:6:6: note: template argument deduction/substitution failed:
m.cpp:11:16: note: template parameters of a template template argument are inconsistent with other deduced template arguments
print(v);
^
怎么解决?
解决方法:
您的编译问题出现是因为您的template template parameter C与std :: vector的声明不匹配:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
如您所见,std :: vector有两个模板参数,而您的C只有一个.但是,请注意第二个参数(类Allocator)具有默认类型参数.从C17开始,即使你编写它也是很好的形式,因为添加模板模板参数匹配不需要为具有默认参数(如Allocator)的参数指定参数.但并非所有编译器都支持对语言规范的修改 – 请参阅here live how Clang 6.0.0 refuses以编译启用了C 17的原始代码段.寻找旧版本的C(或者只是Clang的任何版本),这个片段可能就是你的目标:
template<template<class, class> class C, typename T, typename A>
void print(const C<T, A>& c){
for(auto& e : c)cout<<e<<endl;
}
在这里,您指定类型(std :: vector)的正确模板签名,您稍后将使用实例化print().
无论C 17如何,这都会有效:
template<template<class...> class C, typename T>
void print(const C<T>& c){
for(auto& e : c)cout<<e<<endl;
}
也就是说,请注意,作为vector< int>已经是完全实例化的类型,这个更简单的版本在您的代码段的给定范围内也可以正常工作:
template<typename T>
void print(const T& c){
for(auto& e : c)cout<<e<<endl;
}
I changed print() signature from
(const C& c)
to(C& c)
, it still
fails:
在这种情况下,这可能是更好的做法,因为你没有修改print()中的c.但是,这与您的错误无关.