user
user

Reputation: 23

strange behavior of template argument deduction

The following can compile under c++17

template<class... Ts>
struct Test : Ts...
{
    using Ts::operator()...;
};

template<class... Ts> Test(Ts...) -> Test<Ts...>;


int main() {

    Test test
    {
        [](const int& i) {  },
        [](const float& f) {  }
    };
}

But if I change it to :

    Test test
    ( //{  is changed to (
        [](const int& i) {  },
        [](const float& f) {  }
    );//}  is changed to )

It won't compile, because Test has no such constructor which take 2 parameters.I am wondering why the original code works?

Upvotes: 2

Views: 57

Answers (1)

Sneftel
Sneftel

Reputation: 41542

Because aggregate initialization gets weirder in C++17. Basically, if you aggregate-initialize a class with one or more public base classes, the first elements of the initializer list are used to initialize the base classes. In this case, following template argument deduction, the base classes can be properly initialized from the lambda arguments, using their defaulted copy constructors.

Upvotes: 3

Related Questions