c++ - 模板推演,这符合吗?
问题描述
这段代码似乎不正确,因为我得到了编译器错误。我试图理解为什么:
template <class ... Ts>
struct type_list{};
template <class ... Ts, class T_, class ... Ts_>
auto foo(type_list<Ts...>, Ts&&..., T_&&t, Ts_&&...) {
return sizeof(T_);
}
int main() {
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
return 0;
}
clang 产生以下错误:
example.cpp:16:16: error: no matching function for call to 'foo'
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
^~~
example.cpp:11:6: note: candidate template ignored: deduced conflicting types for parameter 'Ts'
(<int> vs. <>)
auto foo(type_list<Ts...>, Ts&&..., T_&&t, Ts_&&...) {
在我看来,在我的调用中Ts
应该推断为int
(因为这是使第一个论点有效的唯一方法),然后其他所有内容都将被强制执行。为什么这不起作用?
解决方案
ClangTs
从两个相互冲突的来源推导出来:type_list<Ts...>
和Ts&&...
. 因为你调用foo
with type_list<int>{}
,Ts
首先推导出为{int}
。但是,因为最后一个参数Ts_&&...
具有参数包的类型,所以它可以捕获所有内容;在这种情况下,最后两个参数(whileT_&&t
传递给5
),推导出Ts_
为{double, int}
(和T_
as int
)。这Ts
没有任何论据,所以它被推断为{}
。
因此,Clang 的错误消息:Ts
被推断为{}
和{int}
((<int> vs. <>)
在错误消息中)。
请注意,GCC 做的事情不同:
错误:函数'auto foo(type_list,Ts&& ...,T_&&,Ts_&& ...)的参数太少[with Ts = {int}; T_ = 整数;Ts_ = {double, int}]'
它试图保持Ts
推断为{int}
但仍推断Ts_
为{double, int}
,因此无法给出正确数量的参数。
为了进一步解释,请考虑以下内容:
template <class ... Ts>
struct type_list{};
template <class ... Ts>
auto foo(type_list<Ts...>, Ts...) {
return sizeof...(Ts);
}
int main() {
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
}
Clang 正确地指出了这一点,因为这两个推论是冲突的:
注意:候选模板被忽略:推断参数“Ts”的冲突类型(
<int>
vs.<int, double, int>
)
麻烦的是,你不能用另一个参数包捕获 2 个参数,因为如果放在之后(这是你的情况),它会捕获所有东西,或者如果放在之前什么都不会捕获:
template <class ... Ts>
struct type_list{};
template <class... Ts, class... Ts_>
auto foo(type_list<Ts...>, Ts_..., Ts...) {
return sizeof...(Ts);
}
int main() {
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
}
在这里,Clang 产生了相同的错误消息,因为Ts
仍然{int}
从type_list
, 和{int, double, int}
通过捕获所有剩余的参数推导出来。
我认为您唯一的选择是以某种方式处理元组或更明确地调用:(在这种情况下foo<int>(type_list<int>{}, 5, 5.0, 3)
您可能可以删除type_list
)。这样,Ts
不再推断:您明确地 make it {int}
。
推荐阅读
- r - 如何汇总 R 中不完全匹配的列中的值?
- python-3.x - 如何使用已编译的 python 代码(.pyc 文件)运行 Azure 函数?
- amazon-web-services - 在 Lambda 中获取比 lambda 寿命更长的临时信用
- prestashop-1.7 - Prestashop 1.7.8 - 在添加到购物车按钮下移动交付消息
- node.js - NodeJS REPL 双回显输入,难以使用
- authentication - Keycloak 和 C++ 集成
- state - React Typescript 传递状态
- mongodb - 如何根据mongodb中两个集合中的公共列更新列中的数据
- python - 在 PDF 中搜索/更新图形
- react-native - Instagram 或 Facebook 在列表页面上使用什么?