2011-08-09 4 views
40

첫째, 나는 this question을 알고 있지만, 나는 똑같은 것을 묻고 있다고 생각하지 않습니다.emplace_back 작업을 수행하기 위해 push_back을 오버로드 할 수없는 이유는 무엇입니까?

나는 무엇을 알고있다. std::vector<T>::emplace_back인데, 나는 왜 그것을 push_back() 이상으로 사용하는지 이해한다. 가변 인자 템플릿을 사용하여 여러 인자를 새 요소의 생성자에 전달할 수 있습니다.

그러나 C++ 표준위원회에서 새 구성원 기능이 필요하다고 판단한 이유는 무엇인지 이해할 수 없습니다. 단순히 push_back()의 기능을 확장 할 수없는 이유는 무엇입니까? 정상를 rvalue를 호출하거나 것 인수를 포함, 당신은 N 인수를 전달할 수 있도록하면서

template <class... Args> 
void push_back(Args&&... args); 

이, 이전 버전과의 호환성이 손상되지 : 최대한 멀리 볼 수있는, push_back는로 C++ 11에 과부하가 될 수있다 복사 생성자. 사실, push_back()의 GCC C++ (11) 구현은, 어쨌든 emplace_back 호출

void push_back(value_type&& __x) 
    { 
    emplace_back(std::move(__x)); 
    } 

그래서, 내가 그것을 볼 수있는 방법은 emplace_back() 필요가 없다. 추가 할 필요가 있던 것은 모두 가변 인수를받는 push_back()에 대한 오버로드였으며 인수를 요소 생성자에 전달합니다.

내가 틀렸어? 여기에 완전히 새로운 기능이 필요한 몇 가지 이유가 있습니까?

+1

이 비슷합니다 http://stackoverflow.com/questions/4303513/push-back-vs-emplace-back – moka

+7

좋은 질문을. @moka 그는 두 함수의 차이점을 알고 있습니다. 그는 심지어 그 특별한 질문과 관련이 있습니다. –

+0

그들은 서로 다른 의미를 가지고 있습니다. 예를 들어'벡터 v;'에 대해'v.emplace_back (123)'과'v.push_back (123)'을'int'에서 암시 적으로 변환하여 비교하십시오. –

답변

38

T에 명시 적 변환 생성자가있는 경우 emplace_backpush_back 사이에 다른 동작이 있습니다.

struct X 
{ 
    int val; 
    X() :val() {} 
    explicit X(int v) :val(v) {} 
}; 

int main() 
{ 
    std::vector<X> v; 
    v.push_back(123); // this fails 
    v.emplace_back(123); // this is okay 
} 

당신이 push_back 해당 인스턴스 법적 될 것이라고 의미 제안의 변화를 제작하고, 그 행동을 요구하지 않은 가정합니다. 이것이 이유인지 나는 모른다. 그러나 그것이 내가 생각해 낼 수있는 유일한 것이다.

+7

'v.emplace_back (new foo)'가'v.push_back (std :: unique_ptr (new foo))'보다 훨씬 간단하기 때문에'unique_ptr'의 컨테이너를 처리 할 때 특히 유용합니다. 그러나이 경우 변환을 명시 적으로 요청할 수 있어야합니다. –

+0

@AlexandreC .: 사실,'emplace_back (new foo)'는 예외가 아니므로 잘못된 것입니다. – Mehrdad

+0

@Mehrdad 가능한 할당이 실패 할 수 있다는 뜻입니까? 그게 사실이야 ... –

1

다른 예가 있습니다.

솔직히 두는 의미이다 그래서 다른 그와 유사한 동작이 (인해 C++ 특정 구문 "복사 생성자"가 있다는 사실에) 단순히 일치 간주되어야한다.

당신은 당신이 현재 위치에서-건설 의미를 원하는 정말 하지 사용 emplace_back해야하지 않는 한.
그런 일이 필요하지는 않습니다. 일반적으로 push_back은 실제로 의미 론적으로 원하는 것입니다.

#include <vector> 

struct X { X(struct Y const &); }; 
struct Y { Y(int const &); operator X(); }; 

int main() 
{ 
    std::vector<X> v; 
    v. push_back(Y(123)); // Calls Y::operator X() and Y::Y(int const &) 
    v.emplace_back(Y(123)); // Calls X::X(Y const &) and Y::Y(int const &) 
} 
관련 문제