2012-12-19 41 views
9

可能重复:
C++11 emplace_back on vector<struct>?安放一个POD

是进驻可能带豆荚?这似乎并不在Visual Studio 2012的工作:

struct X 
{ 
    int a; 
    int b; 
}; 

void whatever() 
{ 
    std::vector<X> xs; 
    X x = {1, 2}; 

    // okay 
    xs.push_back(x); 

    // okay 
    xs.emplace_back(x); 

    //error C2661: 'X::X': error C2661: no overloaded function takes 2 arguments 
    xs.emplace_back(1, 2); 
} 

这是刚刚的Visual Studio 2012的一个缺点,还是安放一个POD根本不起作用在C++ 11?

+0

它构建它的地方。没有这样的构造函数。 – chris

+0

我不认为它是确定性的,但g ++(4.7.1)也不接受它。 –

+0

我想你可能必须有一个'X'的构造函数,它带有两个参数(如错误消息所示)。 –

回答

5

没有构造函数X::X(int,int),这是您拨打emplace_back将用于构造X对象的内容。容器使用allocator_traits<A>::construct(allocator, p, args)来构造对象,其中p是指向一些分配空间的指针,而args是传递给构造函数的参数。这由emplace_back使用。这construct函数调用::new((void*)p) T(std::forward<Args>(args)...),所以它不使用统一的初始化。

xs.emplace_back({1, 2})也将是一个错误,尽管可以通过列表初始化构造一个聚合。这是因为不能转发大括号包含的初始化程序列表。

+0

对于兼容的编译器可以正常工作,但对于VC++ 2012(尚未)可以正常工作。 : - ] – ildjarn

+3

'emplace_back({1,2})'是一个错误,但'push_back({1,2})'会起作用。列表初始化不能在前者中进行,因为没有什么可以初始化(非正式地说),这是模板论证扣除的必要罪恶。 –

+0

@LucDanton谢谢,你说得对。 –