上下文相关的模板参数推导 - 参数的类型/值不匹配
Posted
技术标签:
【中文标题】上下文相关的模板参数推导 - 参数的类型/值不匹配【英文标题】:Context depended template argument deduction - type/value mismatch at argument 【发布时间】:2020-09-17 14:12:35 【问题描述】:小例子
#include <vector>
#include <tuple>
template<typename T>
void function(std::vector<T> vec)
auto tup = std::tuple<decltype(vec)::iterator>(vec.begin());
int main(int argc, char* args[])
std::vector<int> vec = 1,2,3;
auto tup = std::tuple<decltype(vec)::iterator>(vec.begin());
function(vec);
return 0;
尝试编译给出
error: type/value mismatch at argument 1 in template parameter list for ‘template<class ... _Elements> class std::tuple’
auto tup = std::tuple<decltype(vec)::iterator>(vec.begin());
^
note: expected a type, got ‘decltype (vec)::iterator’
here 描述的解决方案建议添加typename
。将typename
放在function
中的decltype
前面可以解决编译问题。然而:
-
为什么不能推断出类型?
根本问题是什么? (显然编译器怀疑 decltype(...)::iterator 是一种类型。但为什么它在
main
中有效,而在function
中无效?)
【问题讨论】:
鉴于您已标记 C++17(因此 CTAD - 类模板参数推导 - 可用)并且vec.begin()
的类型为 decltype(vec)::iterator
,您可以简单地编写 auto tup = std::tuplevec.begin();
。在 C++11/C++14 中,您可以改用 std::make_tuple()
: auto tup = std::make_tuple(vec.begin());
。
这条评论对我来说和答案本身一样有价值!
【参考方案1】:
由于iterator
是一个依赖名称,所以需要使用typename
关键字来消除歧义:
auto tup = std::tuple<typename decltype(vec)::iterator>(vec.begin());
// ^^^^^^^^
请注意,vec
只是 function
中的一个从属名称。在main
内部它不是依赖的,所以你不需要说typename
。
【讨论】:
以上是关于上下文相关的模板参数推导 - 参数的类型/值不匹配的主要内容,如果未能解决你的问题,请参考以下文章