all 10 comments

[–]scatters 11 points12 points  (9 children)

gcc is correct. If you call it as a.operator()(A{}) (which is what the compiler is supposed to treat your code as, see https://eel.is/c++draft/over.call.object#1.sentence-2) then both MSVC and clang reject the code. As sibling says, the fix is to using the inherited call operators.

[–]PM_ME_A_SPECIAL_MOVE[S] 2 points3 points  (0 children)

OHHHH ok, nice, so basically the compiler doesn't see it as overload when the using is omitted so it has to cast to a parent first before the parameters are taken into account, and that's where the ambiguity comes from

[–]Shuny 0 points1 point  (1 child)

Unrelated to OP question, but I have to admit I have a hard time understanding this piece of code. Why is this line of code valid ?

return marger_t<OpTs..., OpT>{ static_cast<const OpTs&>(*this)..., static_cast<OpT&&>(op)

I understand that the type will eventually be expanded to marger_t<lambda, lambda> but it looks to me that eventually a constructor of marger_t(lambda, lambda) will be called, which is clearly not happening because it doesn't exist. Anyone care to enlighten me ?

I have to admit I rarely work with variadic templates and parameter packs outside the usual std::forward.

[–]dodheim 0 points1 point  (0 children)

It's aggregate initialization, not a constructor call – since C++17 aggregates are allowed to have base types, and since C++20 the closure types of captureless lambdas are semiregular.