简体   繁体   English

空包装的Functor可变参数模板包装扩展在clang ++和g ++中给出了不同的结果

[英]Functor variadic template pack expansion for empty pack gives different results in clang++ and g++

The following code compiles successfully with clang++ 3.8.0 and fails to compile with g++ 7.2.0 (with the -std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors compilation flags): 以下代码可使用clang ++ 3.8.0成功编译,而无法使用g ++ 7.2.0 (带有-std=c++14 -O0 -Wall -Wextra -Werror -pedantic-errors编译标志)编译:

auto foo = [](auto functor, auto... argument_functors)
{
    functor(argument_functors()...);
};

auto do_nothing = [](auto...) {};


int main()
{
    foo(do_nothing);
}

g++ error messages: g ++错误消息:

 main.cpp: In instantiation of '<lambda(auto:1, auto:2 ...)> [with auto:1 = <lambda(auto:3, ...)>; auto:2 = {}]': main.cpp:11:16: required from here main.cpp:3:9: error: no match for call to '(<lambda(auto:3, ...)>) ()' functor(argument_functors()...); ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:6:29: note: candidate: template<class auto:3> <lambda(auto:3, ...)>::operator decltype (((const<lambda(auto:3, ...)>*)((const<lambda(auto:3, ...)>* const)0))->operator()(static_cast<auto:3&&>(<anonymous>))) (*)(auto:3, ...)() const <deleted> auto do_nothing = [](auto...) {}; ^ main.cpp:6:29: note: template argument deduction/substitution failed: main.cpp:3:9: note: candidate expects 1 argument, 0 provided functor(argument_functors()...); ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:6:29: note: candidate: template<class auto:3> <lambda(auto:3, ...)> auto do_nothing = [](auto...) {}; ^ main.cpp:6:29: note: template argument deduction/substitution failed: main.cpp:3:9: note: candidate expects 1 argument, 0 provided functor(argument_functors()...); ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~ 

Which compiler behavior is standard compliant? 哪种编译器行为符合标准?

This is gcc bug 64095 . 这是gcc错误64095

From [dcl.fct]/18 : 来自[dcl.fct] / 18

There is a syntactic ambiguity when an ellipsis occurs at the end of a parameter-declaration-clause without a preceding comma. 当省略号出现在参数声明子句的末尾而没有逗号之前时,存在句法上的歧义。 In this case, the ellipsis is parsed as part of the abstract-declarator if the type of the parameter either names a template parameter pack that has not been expanded or contains auto ; 在这种情况下,如果参数的类型命名未扩展的模板参数包或包含auto ,则省略号将作为abstract-declarator的一部分进行解析。 otherwise, it is parsed as part of the parameter-declaration-clause . 否则,将其解析为parameter-declaration-clause的一部分

Basically, (T...) in a parameter list can be interpreted as either: 基本上,参数列表中的(T...)可以解释为:

  • One unnamed parameter of type T , and an ellipsis. 类型为T一个未命名参数和省略号。
  • A function parameter pack, with types of the template parameter pack T . 具有模板参数包T类型的功能参数包。

The disambiguation rule is supposed to prefer the latter if T is a template parameter pack or auto , but gcc is choosing to interpret this as an ellipsis parameter. 如果T是模板参数pack或auto ,则应该使用消歧规则,后者是首选,但是gcc选择将其解释为省略号参数。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM