继承函数的重载解析

Overload resolution for inherited functions

本文关键字:重载 函数 继承      更新时间:2023-10-16

我想要一个结构,它接受任意数量的lambda,并作为所有调用运算符的中心调用点。

如果调用调用运算符时使用的参数列表与构造中给定的任何lambda都不匹配,则应调用默认调用运算符。

我原以为下面的代码就能做到这一点。每个lambda的调用运算符都通过using"提升"到Poc类中。

template <typename ...Lambdas>
struct Poc : Lambdas...
{
using Lambdas::operator() ...; // Lift the lambda operators into the class
template <typename ...Ts>
auto operator() (Ts...)
{
std::cout << "general call" << std::endl;
}
};
// Deduction guide
template <typename ...Ts>
Poc(Ts... ts)->Poc<Ts...>;
int main()
{
auto l_int = [](int) {std::cout << "int" << std::endl; };
Poc poc{l_int};
poc(1);//calls the default operator. why?
return 0;
}

当结构中没有默认的调用运算符时,一切都会按预期进行(使用有效的参数列表(。如果我将它添加到结构中(如上面的代码中所示(,那么无论我用哪个参数调用它,每次都会调用默认运算符。

根据我的理解,lambda调用运算符和structs(默认(调用运算符存在于同一范围内。因此,它们都应该考虑过载解决方案。由于lamdba运算符比一般默认运算符更具体,因此应该选择它。

显然情况并非如此。为什么?

我在Microsoft Visual C++、Clang和GCC(都是最新版本(上进行了测试。

编辑:

  • MSVC 15.8.9
  • GCC 9.0.0(通过Wandbox(
  • Clang 8.0.0(通过Wandbox(

发现它很简单:您的运算符不是const限定的,而lambda的运算符是(除非您将lambda定义为mutable(。因此,它与Poc的非常数实例更匹配。

只需添加缺失的const:

auto operator() (Ts...) const