自动,带括号和初始化器列表



来自另一个问题:

从 C++17 开始,auto x0{1, 2, 3, 4};,以前推导出初始化器列表,不再被允许(当然,我们可以改用auto x0 = {1, 2, 3, 4};......现在一如既往地避免统一初始化(例如std::vector<int> v({1, 2, 3, 4});,即初始化器列表作为参数的显式构造函数调用(并类似于定义良好的auto x(7);(我自己也不会使用的结构......(,我想出了以下内容:

auto x({1, 2, 3, 4});
// -> std::initializer_list<int> x({1, 2, 3, 4});

这是用GCC 7.2.0(mingw64(编译的,但发出了警告(而注释的版本再次没有(:

非类类型的列表初始值设定项不得用括号括起来

我在标准中找不到任何相关内容,所以现在的问题是(出于纯粹的兴趣......

为什么不允许这样做?(这是标准所涵盖的,还是我们需要将其视为GCC错误?

这是格式不正确的。简而言之,大括号初始化列表不能在模板参数推导中推导,它被认为是非推导上下文。

6( 参数 P,其 A 是大括号的初始化列表,但 P 不是 std::initializer_list 或对 1 的引用:

首先,自动类型推导使用从函数调用中推导模板参数的规则。[dcl.type.auto.deduc]/4

(强调我的(

如果占位符是自动类型说明符,则推导的类型为 T' 替换 T 是使用模板参数的规则确定的 演绎。通过将 auto 的出现次数替换为 要么是新发明的类型模板参数 U,要么是 初始化是复制列表初始化,使用std​::​initializer_­list<U>.使用 从函数调用中推导模板参数,其中 P 是 函数模板参数类型,对应的参数为 e。 如果扣除失败,则声明格式不正确。[ 示例:

const auto &i = expr;

i 的类型是以下发明的函数模板的调用 f(expr( 中参数 u 的推导类型:

template <class U> void f(const U& u);

— 结束示例 ]

注意auto x({1, 2, 3, 4});是直接初始化,不是复制初始化,那么发明的类型模板参数只是U,不是std​::​initializer_­list<U>,对应的参数是{1, 2, 3, 4}

在从函数调用中推导的模板参数中,模板参数不能从大括号的初始化列表中推导出来。[温度扣除呼叫]/1

模板参数推导

是通过将包含参与模板参数推导的模板参数的每个函数模板参数类型(称为 P(与调用的相应参数的类型(称为 A(进行比较来完成的,如下所述。如果从 P 中删除引用和 cv 限定符会为某些 P' 和 N 提供 std::initializer_list 或 P'[N],并且参数是非空的初始值设定项列表 ([dcl.init.list](,则改为对初始值设定项列表的每个元素执行推导,将 P' 作为函数模板参数类型,将初始值设定项元素作为其参数,在 P'[N] 的情况下, 如果 N 是非类型模板参数,则从初始值设定项列表的长度推导 N。否则,初始值设定项列表参数会导致参数被视为非推导上下文 ([temp.deduct.type](。[ 示例:

template<class T> void g(T);
g({1,2,3});                     // error: no argument deduced for T

— 结束示例 ]

最新更新