Tag: c ++ 11

对静态constexpr char 的未定义引用

我想在我的类中有一个static const char数组。 海湾合作委员会抱怨说,我应该使用constexpr ,但现在它告诉我这是一个未定义的参考。 如果我让数组成为非成员,那么它编译。 到底是怎么回事? // .hpp struct foo { void bar(); static constexpr char baz[] = "quz"; }; // .cpp void foo::bar() { std::string str(baz); // undefined reference to baz }

1.0是从std :: generate_canonical有效的输出?

我一直认为随机数在0和1之间, 没有1 ,即它们是半开区间[0,1)的数字。 std::generate_canonical cppreference.com上的文档证实了这一点。 但是,当我运行以下程序: #include <iostream> #include <limits> #include <random> int main() { std::mt19937 rng; std::seed_seq sequence{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; rng.seed(sequence); rng.discard(12 * 629143 + 6); float random = std::generate_canonical<float, std::numeric_limits<float>::digits>(rng); if (random == 1.0f) { std::cout << "Bug!\n"; } return 0; } 它给了我以下输出: Bug! 即它产生了一个完美的1 ,这导致了我的MC集成中的问题。 […]

在C ++ 11中传递值是合理的默认值?

在传统的C ++中,将值传递给函数和方法对于大对象来说是缓慢的,并且通常是不被接受的。 相反,C ++程序员倾向于传递引用,这是更快的,但是引入围绕所有权的各种复杂的问题,尤其是围绕内存pipe理(如果对象是堆分配的话) 现在,在C ++ 11中,我们有Rvalue引用和移动构造函数,这意味着可以实现一个很大的对象(比如std::vector ),这个对象可以很便宜地传入和传出函数。 那么,这是否意味着默认值应该是为types的实例传递值,比如std::vector和std::string ? 那么自定义对象呢? 什么是新的最佳做法?

实际上是为什么重载&&和||的原因 不要短路?

运算符&&和||短路行为 是程序员的一个惊人的工具。 但为什么他们在重载时会失去这种行为? 我明白操作符只是函数的语法糖,但是bool的操作符有这种行为,为什么只能限制在这种单一的types呢? 这背后有没有技术推理?

使用nullptr有什么好处?

这段代码在概念上对三个指针(安全指针初始化)做同样的事情: int* p1 = nullptr; int* p2 = NULL; int* p3 = 0; 那么,分配指针nullptr的优点是分配NULL或0值呢?

何时使用std :: forward来转发参数?

C ++ 0x显示了一个使用std::forward的例子: template<class T> void foo(T&& arg) { bar(std::forward<T>(arg)); } 什么时候使用std::forward是有利的,总是? 另外,它需要在参数声明中使用&& ,在所有情况下都有效吗? 我以为你必须将临时函数传递给一个函数,如果函数是用&&声明的话,那么可以用任何参数调用函数吗? 最后,如果我有这样的函数调用: template<int val, typename… Params> void doSomething(Params… args) { doSomethingElse<val, Params…>(args…); } 我应该用这个来代替: template<int val, typename… Params> void doSomething(Params&&… args) { doSomethingElse<val, Params…>(std::forward<Params>(args)…); } 另外,如果在函数中使用两次参数,即同时转发两个函数,使用std::forward是否明智? 不会std::forward同样的东西临时两次,移动内存,使第二次使用无效? 下面的代码是可以的: template<int val, typename… Params> void doSomething(Params&&… args) { doSomethingElse<val, Params…>(std::forward<Params>(args)…); doSomethingWeird<val, Params…>(std::forward<Params>(args)…); } […]

在C ++ 0x中优化掉“while(1);”

更新,见下文! 我听说过,C ++ 0x允许编译器在下面的代码片段中打印“Hello” #include <iostream> int main() { while(1) ; std::cout << "Hello" << std::endl; } 这显然与线程和优化function有关。 在我看来,这可以让很多人感到惊讶。 有人有一个很好的解释,为什么这是必要的允许? 作为参考,最新的C ++ 0x草案在6.5/5说 一个循环,在for语句的for-init语句之外, 不会调用库I / O函数,并且 不访问或修改易失性对象, 不执行同步操作(1.10)或primefaces操作(第29章) 可能由执行方式假定终止。 [注意:这是为了允许编译器转换,例如删除空循环,即使在无法证实终止的情况下也是如此。 – 结束注意] 编辑: 这篇富有洞察力的文章谈到了这个标准文本 不幸的是,没有使用“未定义的行为”这个词。 然而,只要标准说“编译器可以承担P”,就意味着具有属性not-P的程序没有定义语义。 这是否正确,编译器是否允许为上述程序打印“再见”? 这里有一个更有洞察力的线索 ,是关于对C的一个类似的改变,由Guy做了上面的链接文章。 除了其他有用的事实,他们提出了一个似乎也适用于C ++ 0x的解决scheme( 更新 :这将不再适用于n3225 – 见下文!) endless: goto endless; 编译器不允许优化,看来,因为它不是一个循环,而是一个跳转。 另一个家伙总结了C ++ 0x和C201X的改进build议 通过编写一个循环,程序员断言循环执行一些具有可见行为的事情(执行I […]

如何使我的自定义types使用“基于范围的循环”?

像许多人一样,我一直在尝试C + 11带来的不同function。 我最喜欢的是“基于范围的循环”。 我明白那个: for(Type& v : a) { … } 相当于: for(auto iv = begin(a); iv != end(a); ++iv) { Type& v = *iv; … } 而begin()只是返回标准容器的a.begin() 。 但是,如果我想让我的自定义types“基于范围的循环”意识 ? 我应该专门begin()和end() ? 如果我的自定义types属于命名空间xml ,我应该定义xml::begin()或std::begin()吗? 总之,有什么指导方针呢?

如何在Qt Creator中启用C ++ 11?

标题很自我描述。 我已经下载了Qt Creator 2.7.0,我正在编译一些基本的C ++ 11代码: int my_array[5] = {1, 2, 3, 4, 5}; for(int &x : my_array) { x *= 2; } 我收到以下错误: range based for loops are not allowed in c++ 98 mode 然而,根据这篇文章,这个版本的Qt Creator支持C ++ 11。 那么如何启用它?

C ++中make_shared和normal shared_ptr的区别

std::shared_ptr<Object> p1 = std::make_shared<Object>("foo"); std::shared_ptr<Object> p2(new Object("foo")); 许多谷歌和stackoverflow的职位上有这个,但我不明白为什么make_shared比直接使用shared_ptr更有效率。 有人可以解释我一步一步创build的对象序列和由两者完成的操作,以便我能够了解make_shared是如何有效的。 上面给出了一个例子供参考。