C++ 通过引入不相关的调用运算符(clang vs gcc),奇怪地解决了不明确的调用运算符重载问题
考虑实现一个C++ 通过引入不相关的调用运算符(clang vs gcc),奇怪地解决了不明确的调用运算符重载问题,c++,templates,c++17,overloading,language-lawyer,C++,Templates,C++17,Overloading,Language Lawyer,考虑实现一个重载\u two类的任务,以便编译以下代码: int main() { overload_two o{ [](int) { return 1; }, [](char){ return 2; } }; static_assert(o(0) + o('a') == 3); } 第一次尝试看起来像这样: template <typename F, typename G> struct overload_two : F,
重载\u two
类的任务,以便编译以下代码:
int main()
{
overload_two o{
[](int) { return 1; },
[](char){ return 2; }
};
static_assert(o(0) + o('a') == 3);
}
第一次尝试看起来像这样:
template <typename F, typename G>
struct overload_two : F, G
{
overload_two(F f, G g) : F{f}, G{g} { }
};
此外,clang 13.0.0似乎在没有使用
声明或随机操作符()的情况下工作
我的问题是:
gcc拒绝在没有任何运算符()或使用声明的情况下执行重载\u two
是否正确
gcc使用操作符()(F&)
和使用声明的no接受重载的实现是否正确
clang在不使用任何操作符()或使用声明的情况下接受重载\u two的实现是否正确
对。名称运算符()
的名称查找不明确,因为它在两个基中都找到了名称(请参阅)。这是一个错误,不要通过去,不要收集200美元
对。不相关的操作符()
通过隐藏基类成员使名称查找成功。因为您的lambda是无捕获的,所以它们可以隐式转换为函数指针,并且这些隐式转换由派生类继承。当类可转换为函数指针(或引用)时,将从这些转换中额外生成重载解析。将为示例中的调用选择这些
不,见第1页
<source>:15:22: error: request for member 'operator()' is ambiguous
15 | static_assert(o(0) + o('a') == 3);
| ^
<source>:12:9: note: candidates are: 'main()::<lambda(char)>'
12 | [](char){ return 2; }
| ^
<source>:11:9: note: 'main()::<lambda(int)>'
11 | [](int) { return 1; },
| ^
template <typename F, typename G>
struct overload_two : F, G
{
overload_two(F f, G g) : F{f}, G{g} { }
auto operator()(F&) { } // wtf?
};