问题标签 [list-initialization]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - 嵌套 Boost.Assignment `map_list_of`
是否可以更改此 C++11 初始化:
在不使用临时变量的情况下使用 Boost.Assignment 的某种形式?map_list_of
不幸的是,以这种方式嵌套似乎是不可能的。我错了吗?
注意:我为一些可怕的宏做好了准备。只要它通常可以正常工作就可以了。可变参数模板不行,因为目标编译器是 Intel C++ 2013 和/或 MSVS2012。
编辑:我想使用的“理想”包装界面看起来像这样:
任何地方都/*something*/
可以是空的。这应该同时使用 C++11 大括号 init 或boost::assign::map_list_of
. 我试图避免像这里这样的手动重复:https ://stackoverflow.com/a/1872506/256138
c++ - 是否可以通过列表初始化调用用户定义的转换函数?
这个程序合法吗?
在n2672之后,并由缺陷 978修改,13.3.3.1 [over.best.ics]具有:
4 - 但是,当考虑构造函数或用户定义的转换函数的参数时,它是 13.3.1.7 [...] 的候选 [...] 当初始化器列表只有一个元素并且转换到某个类 X或对(可能是 cv 限定的)X 的引用被认为是 X [...] 的构造函数的第一个参数,仅考虑标准转换序列和省略号转换序列。
这似乎很反常。结果是使用列表初始化强制转换指定转换是非法的:
据我了解n2640,列表初始化应该能够替换直接初始化和复制初始化的所有用途,但似乎没有办法X
从Y
仅使用列表初始化的类型对象构造类型对象:
这是标准的实际意图吗?如果不是,它应该如何阅读或阅读?
c++ - 为什么即使我的类派生自 std::list,也不能从初始化列表中初始化它?
我有以下代码。
我使用 v4.6 的 MinGW g++ 和命令行编译它
g++ -std=c++0x Test.cpp -o test.exe
并得到错误:
error: could not convert '{{800, 400}, {800, 400}}' from '<brace-enclosed initializer list>' to 'PairList'
但如果在 main() 中,我写的
list<pair<unsigned int,unsigned int>> pl = {{800,400},{800,400}};
一切都很好。
怎么回事?
c++ - 列表初始化不能用于私有成员吗?
该代码由 VC++ 2012 编译(最新更新“2012 年 11 月 CTP”)。
我希望 a1 和 a2 是零初始化的,但不是。a1 和 a2 未初始化。
为什么?
c++ - 实现定义的缩小转换?
C++11 形式化了窄化转换的概念,并且不允许在列表初始化的顶层使用一个。
我想知道,给定两种类型T
和U
,是否有可能实现定义从T
to的转换是否U
正在缩小。根据我对标准的阅读,情况就是这样。这是我的推理:
- 根据dcl.init.list (8.5.4) 第 7 段,转换可以缩小的一种方法是,如果它是“从整数类型或无范围枚举类型到不能表示原始值的所有值的整数类型的隐式转换”类型”。
unsigned int
考虑从到的隐式转换long
。- 关于 和 的相对大小
int
,long
C++ 只需要sizeof(int) <= sizeof(long)
. - 考虑一个实现 A,其中
sizeof(int) == sizeof(long)
. 在这个实现中,long
不能代表 的所有值unsigned int
,因此转换会变窄。 - 考虑一个实现 B,其中
sizeof(int) < sizeof(long)
. 在此实现中,long
可以表示 的所有值unsigned int
,因此转换不会缩小。
我的分析是否正确,可以由实现定义转换是否正在缩小?这是可取的吗?
c++ - 为什么标准区分直接列表初始化和复制列表初始化?
我们知道这T v(x);
被称为直接初始化,而T v = x;
被称为复制初始化,这意味着它将构造一个临时T
的x
,将被复制/移动到v
(很可能被省略)。
对于列表初始化,标准根据上下文区分两种形式。T v{x};
称为直接列表初始化,而T v = {x};
称为复制列表初始化:
§8.5.4 [dcl.init.list] p1
[...] 列表初始化可以发生在直接初始化或复制初始化上下文中;直接初始化上下文中的列表初始化称为直接列表初始化,复制初始化上下文中的列表初始化称为复制列表初始化。[...]
但是,整个标准中只有两个参考文献。对于直接列表初始化,在创建T{x}
( §5.2.3/3
) 之类的临时对象时会提到它。对于复制列表初始化,它用于返回语句中的表达式,如return {x};
( §6.6.3/2
)。
现在,下面的代码片段呢?
通常,从X x = expr;
模式来看,我们预计代码无法编译,因为移动构造函数X
定义为delete
d。但是,最新版本的 Clang 和 GCC 可以很好地编译上面的代码,并且在挖掘了一下(并找到上面的引用)之后,这似乎是正确的行为。该标准只定义了整个列表初始化的行为,除了上述几点之外,根本不区分这两种形式。好吧,至少据我所知,无论如何。
所以,再次总结我的问题:
如果它们(显然)做完全相同的事情,那么将列表初始化分成两种形式有什么用?
c++ - 用平凡的ctor对派生类进行统一初始化
我试图用 c++11 统一初始化来解决一些极端情况,但我不知道为什么会这样:
标记为2的行失败,并带有 和 的“没有匹配的 Derived 初始化构造函数”消息。clang 3.1
g++ 4.7
我不明白为什么在 Derived 的情况下,它试图调用构造函数而不执行(我不知道如何调用它,也许是聚合初始化?)就像第 1 行的情况一样)。
以下推理中的某些内容是错误的?:
A)微不足道的保证它可以被静态初始化
B)要静态初始化,不需要在运行时执行任何代码,因此不需要构造函数调用
A+B
=>为什么它试图调用它知道微不足道的类型的构造函数?
我很困惑......
c++ - 使用用户定义的文字初始化 constexpr 数组
简化版
这不会飞,因为在定义数组的那一行不理解文字。但是自由文字函数不能更早移动,因为那时 C 是未知的。
有没有不涉及在代码中添加可变参数模板或类似可怕的东西的解决方案?
c++ - 用大括号初始化标量
在 C 和 C++ 中,可以使用大括号初始化数组和结构:
然而,在2007 年的一次演讲中,Bjarne 提到这种语法也适用于标量。我尝试过这个:
它确实有效!允许使用大括号初始化标量的基本原理是什么?
注意:我特别不是在谈论 C++11 统一初始化。这是很好的旧 C89 和 C++98。
c++ - std::initializer_list 返回值的生命周期
GCC 的实现std::initializer_list
在返回完整表达式的末尾销毁从函数返回的数组。它是否正确?
该程序中的两个测试用例都显示了在值可以使用之前执行的析构函数:
我认为该程序应该可以工作。但是底层的标准语有点复杂。
return 语句初始化一个返回值对象,就像它被声明一样
这从给定的一系列初始化程序初始化一个临时initializer_list
及其底层数组存储,然后initializer_list
从第一个初始化另一个。阵列的寿命是多少?“数组的生命周期与对象的生命周期相同initializer_list
。” 但是其中有两个;哪一个是模棱两可的。8.5.4/6 中的示例,如果它像宣传的那样工作,应该解决数组具有复制到对象的生命周期的歧义。然后返回值的数组也应该存在于调用函数中,并且应该可以通过将其绑定到命名引用来保存它。
在LWS上,GCC 在返回之前错误地杀死了数组,但它initializer_list
根据示例保留了一个命名。Clang 也正确处理了示例,但列表中的对象永远不会被破坏;这会导致内存泄漏。ICC根本不支持initializer_list
。
我的分析正确吗?
C++11 §6.6.3/2:
带有花括号初始化列表的 return 语句通过指定初始化列表中的复制列表初始化 (8.5.4) 初始化要从函数返回的对象或引用。
8.5.4/1:
…复制初始化上下文中的列表初始化称为复制列表初始化。
8.5/14:
以 ...形式发生的初始化
T x = a;
称为复制初始化。
回到 8.5.4/3:
T 类型的对象或引用的列表初始化定义如下:……</p>
— 否则,如果 T 是 的特化
std::initializer_list<E>
,initializer_list
则按如下所述构造对象,并用于根据从相同类型的类中初始化对象的规则(8.5)来初始化对象。
8.5.4/5:
类型的对象
std::initializer_list<E>
是从初始化列表构造的,就好像实现分配了一个E类型的N个元素的数组,其中N是初始化列表中的元素数。该数组的每个元素都使用初始值设定项列表的相应元素进行复制初始化,并且构造对象以引用该数组。如果需要进行窄化转换来初始化任何元素,则程序格式错误。std::initializer_list<E>
8.5.4/6:
数组的生命周期与对象的生命周期相同
initializer_list
。[例子:对于
v1
andv2
,创建的initializer_list
对象和数组{ 1, 2, 3 }
具有完整的表达式生命周期。对于i3
,initializer_list 对象和数组具有自动生命周期。——结束示例]
关于返回一个花括号初始化列表的一点说明
当您返回用大括号括起来的裸列表时,
带有花括号初始化列表的 return 语句通过指定初始化列表中的复制列表初始化 (8.5.4) 初始化要从函数返回的对象或引用。
这并不意味着返回到调用范围的对象是从某物复制而来的。例如,这是有效的:
这不是:
Copy-list-initialization 仅表示使用等效的语法nocopy X = { 3 }
来初始化表示返回值的对象。这不会调用副本,它恰好与 8.5.4/6 中延长数组生命周期的示例相同。
Clang 和 GCC 确实同意这一点。
其他注意事项
对N2640的评论并没有提到这个角落案例。已经对这里组合的各个功能进行了广泛的讨论,但我没有看到任何关于它们的交互的信息。
实现这一点很麻烦,因为它归结为按值返回一个可选的可变长度数组。因为std::initializer_list
它不拥有它的内容,所以该函数还必须返回其他拥有它的东西。当传递给函数时,这只是一个本地的、固定大小的数组。std::initializer_list
但在另一个方向上,VLA 需要与' 的指针一起返回到堆栈中。然后需要告诉调用者是否处理序列(无论它们是否在堆栈上)。
这个问题很容易通过从 lambda 函数返回一个花括号初始化列表来偶然发现,作为一种“自然”的方式来返回一些临时对象而不关心它们是如何包含的。
确实,这与我到达这里的方式相似。但是,省略 trailing-return-type 将是错误的,->
因为 lambda 返回类型推导仅在返回表达式时发生,并且花括号初始化列表不是表达式。