2012-12-19 7 views
9

Powiel możliwe:
C++11 emplace_back on vector<struct>?emplacing strąk

Czy umieszczanie możliwe wstrąkach? Nie wydaje się, aby pracować w 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); 
} 

Czy to po prostu wada Visual Studio 2012, czy też emplacing POD po prostu nie działa w C++ 11?

+0

Konstruuje go na miejscu. Nie ma takiego konstruktora. – chris

+0

Nie uważam tego za ostateczny, ale g ++ (4.7.1) również tego nie akceptuje. –

+0

Myślę, że prawdopodobnie musisz mieć konstruktor dla 'X', który bierze dwa argumenty (jak sugeruje komunikat o błędzie). –

Odpowiedz

5

Nie ma konstruktora X::X(int,int), do tego celu użyłbyś swojego połączenia z emplace_back w celu skonstruowania obiektu X. Kontenery używają allocator_traits<A>::construct(allocator, p, args) do konstruowania obiektów, gdzie p jest wskaźnikiem do przydzielonej przestrzeni, a args są argumentami przekazywanymi do konstruktora. To jest używane przez emplace_back. Ta funkcja construct wywołuje ::new((void*)p) T(std::forward<Args>(args)...), więc nie używa jednolitej inicjalizacji.

xs.emplace_back({1, 2}) będzie również błędem, mimo że agregat można skonstruować z inicjowaniem listy. Dzieje się tak dlatego, że nie można przekazać listy inicjalizującej zamkniętej przez nawiasy klamrowe.

+0

Działa dobrze z zgodnym kompilatorem, ale nie z VC++ 2012 (jeszcze). : -] – ildjarn

+3

'emplace_back ({1, 2})' jest błędem, 'push_back ({1, 2})' zadziała jednak. Inicjowanie listy nie może mieć miejsca w pierwszym, ponieważ nie ma niczego do zainicjowania (nieformalnie), jest to zło konieczne przy odjęciu argumentu szablonu. –

+0

@LucDanton Dzięki, masz rację. –