约束函数的重载解析

303*_*303 5 c++ overloading language-lawyer c++-concepts c++20

调用是否f含糊不清?由于其中一个功能比另一个功能受到更多限制,因此我不希望出现任何歧义。然而,GCC 12.2Clang trunk拒绝代码,与Clang 15MSVC 19.33、 和相比MSVC trunk

代码示例

template<typename...>
int f();

template<typename = void>
int f() requires true;

static_assert(sizeof(f()));
Run Code Online (Sandbox Code Playgroud)

GCC产生的错误:

<source>:7:23: error: call of overloaded 'f()' is ambiguous
    7 | static_assert(sizeof(f()));
      |                      ~^~
<source>:2:5: note: candidate: 'int f() [with <template-parameter-1-1> = {}]'
    2 | int f();
      |     ^
<source>:5:5: note: candidate: 'int f() requires  true [with <template-parameter-1-1> = void]'
    5 | int f() requires true;
      |     ^
Run Code Online (Sandbox Code Playgroud)

use*_*522 2

仅当函数模板在其他方面等效(可能的返回类型除外)时,才会考虑函数模板的可行重载是否受到更多限制。仅仅该调用会含糊不清还不够。

特别是相应的模板参数必须是等效的,请参见[temp.func.order]/6.2.2。作为参数包的模板参数(如在第一个重载中)与不是参数包的模板参数(如在第二个重载中)不同,请参阅[temp.over.link]/6.2

因此,约束对于决定哪个候选人更好并不重要。通话内容含糊不清。