模板参数推论的奇怪行为

时间:2019-03-02 13:39:01

标签: c++ c++17

以下内容可以在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) {  }
    };
}

但是如果我将其更改为:

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

它不会编译,因为Test没有这样的带有2个参数的构造函数。我想知道原始代码为什么起作用?

1 个答案:

答案 0 :(得分:3)

因为在C ++ 17中聚合初始化变得很奇怪。基本上,如果使用一个或多个公共基类对一个类进行聚集初始化,则初始化器列表的第一个元素将用于初始化基类。在这种情况下,可以在推导模板参数之后,使用默认的复制构造函数从lambda参数正确初始化基类。