Есть код с C++Weekly от Jason Turner (только немного изменены имена): https://wandbox.org/permlink/EWlifMBMhvBhSn5B
Info: http://eel.is/c++draft/temp.variadic#5
template <typename... Functors>
struct CompositeVisitor : public Functors...
{
#if 1
template <typename... Args>
CompositeVisitor(Args&&... args) : Functors{std::forward<Args>(args)}...
{
}
#endif
using Functors::operator()...;
};
template <typename... Functors>
CompositeVisitor(Functors...) -> CompositeVisitor<std::decay_t<Functors>...>;
struct Foo {};
struct Bar {};
struct Baz {};
int main() {
CompositeVisitor visitor{
[](const auto&) { std::puts("got some part"); return true; },
[](const Bar&) { std::puts("got Bar"); return false; }
};
Foo foo;
Bar bar;
Baz baz;
visitor(foo);
visitor(bar);
visitor(baz);
}
Clang собирает и работает, GCC не хочет:
prog.cc: In instantiation of 'CompositeVisitor<Functors>::CompositeVisitor(Args&& ...) [with Args = {main()::<lambda(const auto:1&)>, main()::<lambda(const Bar&)>}; Functors = {}]':
prog.cc:30:3: required from here
prog.cc:11:72: error: mismatched argument pack lengths while expanding 'Functors'
11 | CompositeVisitor(Args&&... args) : Functors{std::forward<Args>(args)}...
| ^~~
Если подать типы Functors explicit, то собирается. Только с лямбдами немного накладно сделать.
Баг ли?