c++ - C++ 模板的模板编译失败
问题描述
我有这个测试程序
#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);
^
如何解决?
解决方案
出现编译问题是因为您的模板模板参数 C
与以下声明不匹配std::vector
:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
如您所见,std::vector
有两个模板参数,而您C
只有一个。但是,还要注意第二个参数 ( class Allocator
) 有一个默认类型参数。从 C++17 开始,即使您编写它的方式也是格式良好的,因为添加了模板模板参数匹配不需要为具有默认参数的参数指定参数,例如Allocator
. 但并非所有编译器都支持对语言规范的这种修改——在此处实时查看 Clang 6.0.0 如何拒绝在启用 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;
}
我将 print() 签名从 更改
(const C& c)
为(C& c)
,它仍然失败:
在这种情况下,这可能是更好的做法,因为您没有c
在print()
. 但是,这与您的错误无关。
推荐阅读
- php - Woocommerce:短代码/ PHP 来显示可变产品的当前价格?
- javascript - 无法使用猫鼬按日期获取集合
- android - 无法通过改造协程 API 调用获得下载进度
- reactjs - 带有 MeteorJS 的赛普拉斯:用户不会保持登录状态
- sql - SQL Server - 根据固定长度用 0 动态填充列值
- ios - 与外部开发人员一起使用 Apple Enterprise Program
- postgresql - 如何在一个查询中根据另一个表的值更新列?
- c# - C# GattCharacteristic.WriteValueAsync:TX 大小
- google-apps-script - “执行自定义函数的内部错误”仅在使用该函数的多个单元格之一中
- react-native - AWS Amplify 将二进制帖子中断到 AWS API-Gateway