C++ 模板演绎,是否符合要求?
这段代码似乎不正确,因为我得到了编译器错误。我试图理解为什么:C++ 模板演绎,是否符合要求?,c++,c++11,templates,variadic-templates,C++,C++11,Templates,Variadic Templates,这段代码似乎不正确,因为我得到了编译器错误。我试图理解为什么: 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_); } i
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;
}
模板
结构类型_列表{};
模板
自动foo(类型列表,Ts&&…,T&&&T,Ts&&&…){
返回大小of(T_);
}
int main(){
std::cerrClang从两个相互冲突的来源推断出Ts
:type\u list
和Ts&&…
。因为您使用type\u list{}
调用foo
,Ts
首先被推断为{int}
。但是,由于最后一个参数Ts&&…
具有参数包的类型,因此它可以捕获所有参数;在这种情况下,最后两个参数(而T&&T
被传递5
),这将Ts&
推断为{double,int}
(和T
作为int
).这使得Ts
没有参数,因此推断为{}
因此,Clang的错误消息:Ts
被推断为{}
和{int}
(错误消息中的(vs.)
)
请注意,GCC的做法有所不同:
错误:函数“auto-foo(type_-list,Ts&&…,T_&&&,Ts_&&…[带Ts={int};T_==int;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);
}
模板
结构类型_列表{};
模板
自动foo(类型列表,Ts…){
返回…的大小(Ts);
}
int main(){
C++没有尝试所有的可能性并找到唯一合法的。它遵循非常具体的规则,如果这些规则不起作用,它会生成一个错误
一般来说,如果推断出一个…
包,则该包必须是最后一个包。尝试绕过它将失败
以下是一个可以避免您的问题的解决方案:
template <class ... Ts, class...Us>
auto foo(type_list<Ts...>, Us&&...us) {
return [](Ts&&...ts, auto&& t, auto&&...) {
return sizeof(t);
}(std::forward<Us>(us)...);
}
int main() {
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
return 0;
}
模板
自动foo(类型列表,美国和…美国){
返回[](Ts&&…Ts,auto&&t,auto&&…){
返回大小f(t);
}(标准:远期(美国)…);
}
int main(){
std::cerr编译器应该如何决定推断哪个Ts
?@Fureeish@NirFriedman您有什么理由想直接使用type\u list
函数参数而不是模板参数吗?非常感谢您提供的替代解决方案!
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);
}
template <class ... Ts, class...Us>
auto foo(type_list<Ts...>, Us&&...us) {
return [](Ts&&...ts, auto&& t, auto&&...) {
return sizeof(t);
}(std::forward<Us>(us)...);
}
int main() {
std::cerr << foo(type_list<int>{}, 5, 5.0, 3);
return 0;
}