继承函数的重载解析

我希望有一个结构,该结构可以接受任意数量的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;
}

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

以我的理解,lambda-call-operators和structs(默认)call-operator存在于同一作用域中。 因此,应该全都考虑它们的过载分辨率。 由于lamdba-operator比通用默认操作符更具体,因此应选择它。

显然不是这样。 这是为什么?

我在Microsoft Visual C ++,Clang和GCC(均为最新版本)上进行了测试。

编辑:

  • MSVC 15.8.9
  • GCC 9.0.0(通过Wandbox)
  • 铛8.0.0(通过Wandbox)
LcdDrm asked 2019-11-15T22:49:47Z
1个解决方案
43 votes

当您发现它时很简单:您的运算符不是const合格的,而lambda是合格的(除非您将lambda定义为mutable)。 因此,它与您的Poc的非常量实例更好地匹配。

只需添加缺少的const

auto operator() (Ts...) const
Quentin answered 2019-11-15T22:50:18Z
translate from https://stackoverflow.com:/questions/53173336/overload-resolution-for-inherited-functions