I alighted on this while permuting with a trivial piece of code:
struct Base0 {};
struct Base1 {};
template<typename... Ts>
struct Derived: Ts... {};
int main() {
Derived<Base0, Base1> d0 {Base0{}, Base1{}}; // OK
Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
}
I thought both d0 and d1 should have resulted in a compilation error since I can't see how Derived without any matching ctor takes ctor arguments as passed and flags d0's compilation as fine.
There's probably something obvious I'm missing. What is it about the uniform initialisation that's making it pass ? Is it aggregate initialisation or something ? What's happening with the temporaries passed to the ctor ?
Using C++17 online compiler here
Edit
As asked, I'm providing a copy-paste of the spew-out:
main.cpp: In function ‘int main()’:
main.cpp:9:47: error: no matching function for call to ‘Derived::Derived(Base0, Base1)’
Derived<Base0, Base1> d1 (Base0{}, Base1{}); // ERROR
^
main.cpp:5:8: note: candidate: constexpr Derived::Derived()
struct Derived: Ts... {};
^~~~~~~
main.cpp:5:8: note: candidate expects 0 arguments, 2 provided
main.cpp:5:8: note: candidate: constexpr Derived::Derived(const Derived&)
main.cpp:5:8: note: candidate expects 1 argument, 2 provided
main.cpp:5:8: note: candidate: constexpr Derived::Derived(Derived&&)
main.cpp:5:8: note: candidate expects 1 argument, 2 provided
make_uniqueoremplace. - Davis Herring