从到数组的引用构造没有被选择为列表初始化

问题描述 投票:1回答:1

考虑下面的结构:

struct A {
    template<typename T, std::size_t N>
    A(T const(&array)[N]) {}

    template<typename T, std::size_t N>
    A& operator=(T const(&array)[N]) { return *this; }
 };

编码:

// a is of type A
a = {1, 2, 3, 4};

编译就好,由于std::initialiser_list隐式转换为数组引用。

然而,

A a {1, 2, 3, 4};
A a = {1, 2, 3, 4};

失败既锵和GCC编译。当我再补充一点接受std::initialiser_list<T>构造它编译。

我在想什么?

c++ c++17 list-initialization
1个回答
2
投票

你只需要额外的括号或括号:

A a{{1, 2, 3, 4}}; // ok
A b({1, 2, 3, 4}); // ok

这样做的原因是外部大括号/括号是为A和内部括号是,你是列表初始化array对象。

与分配对象,你不需要额外的括号或大括号,因为他们只需通过函数调用暗示:

a = {1, 2, 3, 4};

相当于:

a.operator=({1, 2, 3, 4});

或多或少。


当我再补充一点接受std::initialiser_list<T>构造它编译。

为了详细说明清单初始化是如何工作的。当你写A a{1, 2, 3, 4},我们正在寻找第一个对一些std::initializer_list<T>构造(我们还没有的,所以没有找到一个),然后寻找,我们可以用四个参数调用构造函数(不存在)。添加额外的()s或{}s意味着我们正在寻找,我们可以用我们与1, 2 ,3, 4初始化一个参数调用构造函数。

一旦添加了std::initializer_list<T>构造,现在这对初始化是第一阶段可行的候选者。


需要注意的是这样的:

编译就好,由于std::initialiser_list隐式转换为数组引用。

是不正确的。没有std::initializer_list在这个问题上的任何地方。 {1, 2, 3, 4}在C ++中一个有趣的事情。它没有一个类型或任何东西。这只是一个支撑,初始化列表。它只是基于我们赋予它意义的上下文。在这种情况下,这并不是说会转换为不同的东西的事......它只是一个初始化为数组的集合。

© www.soinside.com 2019 - 2024. All rights reserved.