我希望有一个结构,该结构可以容纳任意数量的lambda,并作为所有调用运算符的中央调用点。
如果调用操作符使用的参数列表与构造中给出的任何lambda不匹配,则应调用默认的调用操作符。
我认为以下代码可以准确地完成此任务。通过Poc
将每个lambda的调用运算符“提升”到using
类中。
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-operator和structs(默认)call-operator存在于同一作用域中。因此,应该全都考虑它们的过载分辨率。由于lamdba-operator比通用默认操作符更具体,因此应选择它。
显然不是这样。为什么会这样?
我在Microsoft Visual C++,Clang和GCC(均为最新版本)上进行了测试。
编辑:
答案 0 :(得分:43)
发现它很简单:您的运算符没有const
的资格,而the lambda's one是合格的(除非您将lambda定义为mutable
)。因此,它更适合您的Poc
的非常量实例。
只需添加丢失的const
:
auto operator() (Ts...) const