如果可能,构造函数应该通过初始化列表初始化其所有成员对象.它比通过构造函数体内的赋值构建构造函数更有效.
有人可以解释一下,为什么在一个例子的帮助下使用初始化列表更有效率?
我有从单个超类型派生的不同类型的对象.我想知道std::initializer在循环范围内使用list 是否有任何缺点,如下所示:
for(auto object: std::initializer_list<Object *>{object1, object2, object3}) {
}
Run Code Online (Sandbox Code Playgroud)
它是完全正常和有效还是使用阵列会更好?对我来说,std::array解决方案似乎对编译器更具限制性,并且存在明确说明大小的缺点:
for(auto object: std::array<Object*, 3>{object1, object2, object3}) {
}
Run Code Online (Sandbox Code Playgroud)
是否有任何其他或更好的方法迭代明确给定的对象列表?
让我们看一下基于循环的以下简单范围:
int a = 5, b = 6;
for (auto & i : {a, b})
{
std::cout << i << std::endl; // Works as expected.
i = 3; // Error!
}
Run Code Online (Sandbox Code Playgroud)
gcc抱怨assignment of read-only reference 'i',暗示与初始化列表一起使用的基于for循环的范围隐式const地为引用添加了一个限定符,完全没有说明.
我知道我可以使用字符数组和初始化列表来填充字符串.
它看起来编译器从int到initializer_list或allocator进行了一些隐式的提升.但我不知道为什么它没有给我任何警告,为什么它暗示它.
你能解释一下字符串s4和s5会发生什么吗?
#include <iostream>
#include <string>
using namespace std;
class A{
};
int main() {
// string::string(charT const* s)
string s1("12345");
// 5 - because constructor takes into account null-terminated character
cout << s1.size() << endl;
// string(std::initializer_list<charT> ilist)
string s2({'1','2','3','4','5'});
// 5 - because string is built from the contents of the initializer list init.
cout << s2.size()<<endl;
// string::string(charT const* s, size_type count)
string s3("12345",3);
// 3 - Constructs the string with the first count characters …Run Code Online (Sandbox Code Playgroud) 假设您有一个类型变量,std::vector<std::string>并使用初始化列表初始化它:
using V = std::vector<std::string>;
V v = { "Hello", "little", "world", "of", "move", "semantics" };
Run Code Online (Sandbox Code Playgroud)
编译器将为std::string每个字符串文字创建一个临时文件,在这些文件上创建一个初始化列表,然后调用ctor V并创建向量.ctor不知道所有这些字符串都是临时字符串,所以它正在复制每个字符串.
我没有在标准中找到任何允许矢量ctor在临时时移动元素的东西.
我错过了什么或使用初始化程序列表导致不必要的副本?我正在编写类,这个问题可能会导致代码效率低下.任何避免不必要的副本的技术将不胜感激.
我有一个关于卷括号括号列表的不同含义的问题.
我知道C++ 03不支持C++ 11 initializer_list.然而,即使没有-std=c++11编译器标志,gcc 6.3 也会interpolate使用以下代码正确初始化:
map<string, string> interpolate = { { "F", "a && b && c" }, { "H", "p ^ 2 + w" }, { "K", "H > 10 || e < 5" }, { "J", "F && !K" } };
Run Code Online (Sandbox Code Playgroud)
我被问到为什么这会起作用,我意识到我没有答案.这是一个Brace-Init-List,但我们从初始化标准容器的方式通常是通过initializer_list.那么非C++ 11代码如何完成初始化呢?
今天在我的项目中遇到内存问题,使用c ++ 11 initializer_list的类.系统发出内存问题:dbgdel.cpp中的表达式_BLOCK_TYPE_IS_VALID(pHead-> nBlockUse).我将代码简化为一个简单的示例,它不再抛出表达式,但问题从调试输出中变得明显.在我看来这个代码是正确的,它似乎也适用于g ++.
#include <functional>
#include <memory>
#include <string>
#include <iostream>
#include <vector>
#include <map>
#include <sstream>
#include <initializer_list>
using namespace std;
class B {
public:
char data[256];
B(const string& x) {
cout << "Init " << this << endl;
}
B(const B& b) {
cout << "Copy " << this << endl;
}
~B() {
cout << "Deleting b " << this << endl;
}
};
class C {
public:
vector<B> bs;
C(initializer_list<B> bb) {
for(auto& …Run Code Online (Sandbox Code Playgroud) 来自另一个问题:
由于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});
Run Code Online (Sandbox Code Playgroud)
这是用GCC 7.2.0(mingw64)编译的,但是发出警告(而评论版再次没有):
list-initializer for non-class type must not be parenthesized
我在标准中找不到任何相关内容,所以现在的问题是(出于纯粹的兴趣......):
为什么不允许这样做?(这是否被标准所涵盖,或者我们是否需要将此视为GCC错误?)
当使用包含多个braced-init-list的braced-init-list时,B,C和D标准定义的规则是什么?
对于B,我相信这个场景在标准中定义为带有单个元素的braced-init-list,因此它Test(int)直接调用没有临时 - 但我无法找到位置.
对于C和D,我不确定这是否是未定义的行为.
我也对使用多个元素时发生的情况感兴趣,即{{{1, 2}}}如果这改变了B,C或D的行为?
#include <iostream>
struct Test {
Test(const int a) {
// A and B call this
}
Test(Test&& test) = delete;
Test(const Test& test) = delete;
};
int main()
{
Test a{1}; // calls Test(int)
Test b{{2}}; // B
Test c{{{3}}}; // C
Test d{{{{4}}}}; // D
// Test e{a}; error, deleted copy constructor
// Test f{Test{0}}; error, deleted move constructor
return 0;
}
Run Code Online (Sandbox Code Playgroud)
GCC只g++ my_prog.cpp给出了C和D的错误:
my_prog.cpp: In …Run Code Online (Sandbox Code Playgroud) 假设我有一个采用类对象的模板函数:
template<class T>
void Foo(T obj);
Run Code Online (Sandbox Code Playgroud)
和一个类定义如下:
class Bar
{
public:
Bar(int a, bool b): _a(a), _b(b) {}
private:
int _a;
bool _b;
};
Run Code Online (Sandbox Code Playgroud)
有没有办法让下面的代码编译?
Foo<Bar>(5,false);
Foo<Bar>({5,false}); // i know this works, just wondering if i can remove the brackets somehow.
Run Code Online (Sandbox Code Playgroud) c++ ×10
initializer-list ×10
c++11 ×5
constructor ×2
c++03 ×1
c++14 ×1
c++17 ×1
const ×1
for-loop ×1
gcc ×1
initializer ×1
performance ×1
range ×1
string ×1
visual-c++ ×1