turingwy

关于vs2013的bug

#include <iostream>

#include <memory>

#include <initializer_list>

#include<string>

using namespace std;


class test {

int a;

int b;

public:

test(initializer_list<int> a) {


}


test(int a) {


}

private:

test(const test &a) {

cout << "123";

}


};

int main() {

initializer_list<int> b = { 12, 2, 3 };

test a = b;

}


c++11中引入了一个新的类initializer_list 这个类是一个模板类,他使得用户可以定义一个构造函数,它的参数是initializer_list类型,我们使用这个函数定义一个对象时就可以使用:

test a = {1,2,3};的方式

也可以使用test a({1,2,3}) 或者test a(initializer_list<int>({1,2,3}))

如果使用第一种方式,并不是使用了拷贝构造函数,而是编译器开的外挂。也就是说这种方式不管拷贝构造函数有没有都可以使用


但是如果想代码中那样,test a = b;

这就使用了拷贝构造函数,拷贝构造函数自动的用b生成了一个临时test变量,然后调用了拷贝构造。

根据这一点,如果我们把拷贝构造函数设为private,在G++中编译无法通过,但在vs2013中仍然可以通过。

c++ primer书中说到,编译器可以跳过拷贝构造而直接使用test a(b),但是不过怎样,必须保证拷贝构造函数是可用的。vs违反了这一点。


同样的例子 test接受一个int变量的构造函数,test a = 12在G++中无法通过,因为首先12被隐式转换为test,然后调用拷贝构造函数,而拷贝构造函数是private的,所以编译失败。但在vs中却可以通过,很明显,vs的编译器把test a = 12 变成了test a(12)

而G++没有。


评论

热度(5)