Tag: c ++ 11

为什么编译器会在编译错误时将不正确的参数types传递给struct initialiser list?

我定义了一个结构体,它有一个构造函数: struct MyStruct { MyStruct(const int value) : value(value) { } int value; }; 和以下对象: int main() { MyStruct a (true); MyStruct b {true}; } 但是我没有收到任何编译错误,无论是MVS2015或Xcode 7.3.1。 为什么我没有收到任何编译错误? 我如何让编译器帮我检测到这个? (最初,结构被写成具有bool数据,但一段时间后,代码改变了, bool变成了int ,引入了一些错误。)

覆盖纯虚函数时,有没有使用`override`的意思?

例如: class Base { virtual void my_function() = 0; }; class Derived : Base { void my_function() override; }; 从我所读到的, override关键字被用来确保我们在正在被覆盖的函数中有正确的签名,并且它似乎是它唯一的用法。 但是,在纯虚函数的情况下,如果我们在Derived类(或者Base类,依赖于如何看待事物)中使用了不正确的签名,那么编译器会抛出一个错误。 那么,在Derived::my_function()声明的末尾添加override是否有任何意义?

带有return的C ++析构函数

在C ++中,如果我们定义一个类的析构函数为: ~Foo(){ return; } 一旦调用这个析构函数, Foo的对象就会被销毁,或者从析构函数中显式返回,这意味着我们永远不会想要销毁它。 我想这样做只有通过另一个对象析构函数才能销毁某个对象,也就是说只有当另一个对象准备销毁时才能销毁它。 例: class Class1{ … Class2* myClass2; … }; Class1::~Class1(){ myClass2->status = FINISHED; delete myClass2; } Class2::~Class2(){ if (status != FINISHED) return; } 我在网上search,似乎无法find我的问题的答案。 我也尝试通过一些代码一步一步地debugging,但不能得出一个结论性的结果。

并发编程的C + +?

我一直听说每个地方的并发编程。 你们可以点亮一下它是什么,以及c ++新标准如何促进这样做?

std ::线程调用类的方法

可能重复: 用成员函数启动线程 我有一个小class: class Test { public: void runMultiThread(); private: int calculate(int from, int to); } 如何从方法runMultiThread()中的两个线程calculate两个不同的参数集(例如calculate(0,10) , calculate(11,20) runMultiThread() ? PS谢谢,我已经忘记,我需要通过this ,作为参数。

本地类中的成员模板

给出以下代码: void f() { class A { template <typename T> void g() {} }; } g ++ 4.4(还有g++-4.6 -std=gnu++0x )抱怨:“本地类中成员模板声明无效”。 显然本地类不允许有模板成员。 这个限制的目的是什么? 它会被删除在C ++ 0x? 注意:如果我将本地类本身作为模板,而不是给它一个模板成员: void f() { template <typename T> class A { void g() {} }; } 我得到“错误:模块声明不能出现在块作用域”。

在std :: array初始化中使用Brace elision

假设有一个std::array被初始化。 没关系,如果使用双花括号: std::array<int, 2> x = {{0, 1}}; std::array<int, 2> x{{0, 1}}; 在旧的聚合初始化中使用单个大括号也是可以的,因为大括号将会照顾大括号: std::array<int, 2> x = {0, 1}; 但是,使用单个大括号进行列表初始化可以吗? GCC接受它,Clang拒绝使用“在使用直接列表初始化时,不能忽略子对象初始化时的括号”。 std::array<int, 2> x{0, 1}; 提到大括号的唯一部分是8.5.1 / 12,它说: 使用赋值expression式初始化聚合成员时,将考虑所有隐式types转换(第4章)。 如果赋值expression式可以初始化一个成员,则该成员被初始化。 否则,如果该成员本身是一个子集合,则假定支撑精确,并且为该子集合的第一个成员的初始化考虑赋值expression式。 8.5.1是关于具体的聚合初始化的,所以应该表示铿锵拒绝是正确的吧? 没那么快 8.5.4 / 3说: Ttypes的对象或引用的列表初始化定义如下: […] – 否则,如果T是聚合,则执行聚合初始化(8.5.1)。 我认为这意味着与汇总初始化(包括大括号)一样的规则也适用,这意味着GCC是正确的接受。 我承认,措辞不是特别清楚。 那么,哪个编译器对待第三个片段是正确的呢? 大括号是否在列表初始化中发生,或者不是?

GCC的所有版本都与在定义中具有默认types的模板拼争

我浪费了无数个小时来查明gcc的问题。 我想用另外一个编译器来testing我们的代码库,以寻找更多的Clang可能错过的警告。 我感到震惊的是,由于模板论证扣除的失败,几乎有一半的项目停止编译。 在这里,我试图把我的情况弄到最简单的一段代码。 #include <type_traits> struct Foo { }; // This is a template function declaration, where second template argument declared without a default template <typename T, typename> void foo(const Foo & foo, T t); // This is a template function definition; second template argument now has a default declared template <typename T, typename […]

为什么C ++ 0x中没有编译器生成的swap()方法?

C ++编译器自动生成拷贝构造函数和拷贝赋值操作符。 为什么不swap呢? 现在,实现复制赋值运算符的首选方法是复制和交换方式: T& operator=(const T& other) { T copy(other); swap(copy); return *this; } ( 忽略使用按值传递的复制易用表单 )。 这个习惯用法的优点是在exception情况下是事务性的(假设swap实现不会抛出)。 相比之下,默认的编译器生成的复制赋值操作符recursion地对所有基类和数据成员进行复制赋值,并且不具有相同的exception安全保证。 同时,手动实现swap方法是很繁琐和容易出错的: 为了确保swap不会丢失,必须为所有非POD成员在类和基类中,在非POD成员中执行。 如果一个维护者向类中添加一个新的数据成员,维护者必须记得修改该类的swap方法。 如果不这样做可能会引入微妙的错误。 另外,因为swap是一个普通的方法,所以如果swap实现不完整,编译器(至less我不知道的)不会发出警告。 如果编译器自动生成swap方法不是更好吗? 然后隐式复制分配实现可以利用它。 显而易见的答案可能是:当开发C ++时,copy-and-swap成语不存在,现在这样做可能会破坏现有的代码。 不过,也许人们可以select让编译器使用C ++ 0x用于控制其他隐式函数的相同语法来生成swap : void swap() = default; 然后可能会有规则: 如果存在编译器生成的swap方法,则可以使用“复制和交换”来实现隐式复制分配操作符。 如果没有编译器生成的swap方法,将像以前一样实现隐式的复制分配操作符(在所有基类和所有成员上调用复制分配)。 有谁知道C ++标准委员会是否已经提出了这样的(疯狂的)事情,如果有的话,委员会成员有什么意见?

xvalues,glvalues和prvalues的真实生活的例子?

我想知道是否有人能够说出或解释一些xvalues,glvalues和prvalues的真实生活的例子? 我读过类似的问题: 什么是右值,左值,左值,右值和左值? 但我不明白大家的意思。 任何人都可以解释在什么情况下,这些价值观是重要的,何时应该使用它们?