Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 列表初始值设定项和变量构造函数_C++_Templates_C++11_Initializer List_Variadic - Fatal编程技术网

C++ 列表初始值设定项和变量构造函数

C++ 列表初始值设定项和变量构造函数,c++,templates,c++11,initializer-list,variadic,C++,Templates,C++11,Initializer List,Variadic,从列表中初始化: 否则,将分两个阶段考虑T的施工人员: 所有将std::initializer_list作为唯一参数或将其作为第一个参数(如果其余参数具有默认值)的构造函数都将被检查,并通过重载解析与std::initializer_list类型的单个参数进行匹配 如果前一个阶段没有生成匹配项,则T的所有构造函数都会参与针对由大括号init列表元素组成的参数集的重载解析,限制条件是只允许非收缩转换。如果此阶段生成显式构造函数作为副本列表初始化的最佳匹配,编译将失败(注意,在简单副本初始化中,

从列表中初始化:

否则,将分两个阶段考虑T的施工人员:

  • 所有将std::initializer_list作为唯一参数或将其作为第一个参数(如果其余参数具有默认值)的构造函数都将被检查,并通过重载解析与std::initializer_list类型的单个参数进行匹配

  • 如果前一个阶段没有生成匹配项,则T的所有构造函数都会参与针对由大括号init列表元素组成的参数集的重载解析,限制条件是只允许非收缩转换。如果此阶段生成显式构造函数作为副本列表初始化的最佳匹配,编译将失败(注意,在简单副本初始化中,根本不考虑显式构造函数)

因此,首先考虑使用
初始值设定项\u list
的构造函数。否则,列表中的每个元素都会被视为构造函数的参数。然而

#include <iostream>

using namespace std;

struct A{
    template <typename... Args> A(Args... li) { cout << sizeof...(Args) << endl;}
};

int main(){

    A a = {2,3,4};

}
#包括
使用名称空间std;
结构A{
模板A(Args…li){cout

[temp.decrete.call]/1通过比较每个函数模板参数类型(调用它
p
)与调用的相应参数类型(调用它
A
)来完成模板参数推断如下所述。如果从
P
中删除引用和cv限定符会给出
std::initializer\u列表

,如果您明确提供了一个带有

std::initializer\u列表的构造函数,则将选择:

模板A(Args…
不是具有第一个参数的构造函数
std::initializer\u list
(即使第一个参数可能是
std::initializer\u list


A={2,3,4}
中,
{2,3,4}
没有类型。它不是一个
std::initializer\u列表

只是要清楚,一个
initializer\u列表
参数将导致
A(Args…
)中成功的模板参数推断。因此,我的CPP引号的第一行(转换为
初始化器列表
参数)适用于查找候选非模板构造函数,而您的报价适用于使用模板参数推断查找候选模板函数。如果模板函数或非模板函数均未提供合适的候选函数,则每个列表元素都被视为单独的参数。[dcl.init.list]/2中有一条注释:“将初始值设定项列表作为参数传递给类
C
的构造函数模板
template C(T)
,并不会创建初始值设定项列表构造函数,因为初始值设定项列表参数会导致相应的参数为非推断上下文(14.8.2.1)。”这就是导致我选择[temp.Decrete.call]的原因。现在,将程序中的
main
更改为
std::initializer\u list l{2,3,4};A=l;
确实可以编译。我不确定为什么。啊。[temp.decreate.call]/1讨论了参数是初始值设定项列表的情况(即,用大括号括起来的逗号分隔的值序列),而不是std::initializer\u list的实例。区别很重要,两者不能互换。