Chr*_*etz 5 c++ templates c++11
以下代码无法编译并显示以下错误template template argument has different template parameters than its corresponding template template parameter
:
#include <tuple>
#include <vector>
#include <string>
#include <iostream>
template<template<typename, typename> class Blah, typename KeyType, typename ValueType>
void print_tuploid(const Blah<KeyType, ValueType>& tup) {
std::cout << "first value: " << std::get<0>(tup) << " second value: " << std::get<1>(tup) << std::endl;
}
int main() {
auto stuff = std::make_tuple(1, 2);
print_tuploid(stuff);
}
Run Code Online (Sandbox Code Playgroud)
该代码背后的初衷无关紧要,在这一点上,我只是想了解为什么认为这是无效的。
如果将调用更改std::make_tuple
为std::make_pair
,则代码会正确编译并运行,这使我相信特定于的事情很奇怪std::tuple
。
我最初以为std::tuple
可能会有一些我不知道的额外的默认模板参数,因为如果我将以下定义更改为print_tuploid
,则代码会同时为std::make_tuple
和编译std::make_pair
:
template<template<typename...> class Blah, typename KeyType, typename ValueType>
void print_tuploid(const Blah<KeyType, ValueType>& tup) {
std::cout << "first value: " << std::get<0>(tup) << " second value: " << std::get<1>(tup) << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试转储stuff
使用以下代码的推导类型时:
#include <tuple>
template<typename T>
class TypePrinter;
int main() {
auto stuff = std::make_tuple(1, 2);
TypePrinter<decltype(stuff)> error;
}
Run Code Online (Sandbox Code Playgroud)
它报告:implicit instantiation of undefined template 'TypePrinter<std::__1::tuple<int, int> >'
,这使我相信事实并非如此。
此外,作为附带的问题,为什么在这种情况下不会发生参考折叠?以下代码也被视为无效:
#include <iostream>
template<template<typename, typename> class Blah, typename KeyType, typename ValueType>
void print_tuploid(Blah<KeyType, ValueType>&& tup) {
std::cout << "first value: " << std::get<0>(tup) << " second value: " << std::get<1>(tup) << std::endl;
}
int main() {
auto stuff = std::make_pair(1, 2);
print_tuploid(stuff);
}
Run Code Online (Sandbox Code Playgroud)
给出错误:no known conversion from 'std::__1::pair<int, int>' to 'pair<int, int> &&' for 1st argument
。
基本上,我只是想通过了解到底发生了什么来扩展我的模板知识。很抱歉,冗长的帖子,在此先感谢任何人都可以提供的任何指导。
该函数的问题在于,它与正好带有2个参数的模板类匹配。实际上,std::tuple
具有的模板签名template <typename...>
。区别在于它tuple
需要任意数量的模板参数,而您的函数需要2。
std::pair
可以正常工作,因为模板签名template <typename, typename>
完全匹配。
有一个建议,尽管我找不到最新版本,但可以启用这种专业化。它似乎已经传入C ++ 17或至少与之类似的东西,因为模板模板参数的cppreference页认为这是一个有效的示例。我找到的建议在这里。
第二个版本不接受std::pair
的原因是因为它需要右值引用。一旦拥有(部分)专用类型,就不能将其&&
视为转发参考。
归档时间: |
|
查看次数: |
292 次 |
最近记录: |