push_back 대 emplace_back
나는 조금의 차이에 대한 혼란 스러워요 push_back
와 emplace_back
.
void emplace_back(Type&& _Val);
void push_back(const Type& _Val);
void push_back(Type&& _Val);
push_back
rvalue 참조를받는 오버로드 가 있기 때문에 그 목적이 무엇인지 잘 모르겠습니다 emplace_back
.
방문자가 말한 것 외에도 :
void emplace_back(Type&& _Val)
MSCV10에서 제공하는 기능 은 push_back(Type&& _Val)
.
그러나 실제 C ++ 0x 형식 emplace_back
은 정말 유용합니다. void emplace_back(Args&&...)
;
a를 취하는 대신 value_type
가변적 인 인수 목록을 사용하므로 이제 인수를 완벽하게 전달하고 임시없이 컨테이너에 객체를 직접 구성 할 수 있습니다.
RVO와 이동 시맨틱이 아무리 영리 해져도 push_back이 불필요한 복사 (또는 이동)를 만들 가능성이있는 복잡한 경우가 있기 때문에 유용합니다. 예를 들어,의 기존 insert()
기능 std::map
을 사용하는 경우 임시를 만들어야합니다.이 임시 파일 std::pair<Key, Value>
은에 복사 된 다음지도에 복사됩니다.
std::map<int, Complicated> m;
int anInt = 4;
double aDouble = 5.0;
std::string aString = "C++";
// cross your finger so that the optimizer is really good
m.insert(std::make_pair(4, Complicated(anInt, aDouble, aString)));
// should be easier for the optimizer
m.emplace(4, anInt, aDouble, aString);
그렇다면 MSVC에서 올바른 버전의 emplace_back을 구현하지 않은 이유는 무엇입니까? 사실, 너무 오래전에 저를 괴롭 혔기 때문에 Visual C ++ 블로그 에서 같은 질문을했습니다 . 다음은 Microsoft에서 Visual C ++ 표준 라이브러리 구현의 공식 관리자 인 Stephan T Lavavej의 답변입니다.
Q : 베타 2 emplace 함수는 현재 일종의 자리 표시 자일까요?
A : 아시다시피 가변 템플릿은 VC10에서 구현되지 않습니다.
make_shared<T>()
, 튜플 및 .NET의 새로운 항목에 대한 전 처리기 기계로 시뮬레이션합니다<functional>
. 이 전 처리기 기계는 사용 및 유지 관리가 상대적으로 어렵습니다. 또한 반복적으로 하위 헤더를 포함해야하므로 컴파일 속도에 큰 영향을줍니다. 시간 제약과 컴파일 속도 문제의 조합으로 인해 emplace 함수에서 가변 템플릿을 시뮬레이션하지 않았습니다.가변 템플릿이 컴파일러에서 구현되면 emplace 함수를 포함하여 라이브러리에서이를 활용할 수 있습니다. 우리는 준수를 매우 중요하게 생각하지만 안타깝게도 모든 것을 한꺼번에 할 수는 없습니다.
이해할 수있는 결정입니다. 전 처리기 끔찍한 트릭으로 가변 템플릿을 에뮬레이트하려고 한 번만 시도한 모든 사람은이 항목이 얼마나 역겨운 지 알고 있습니다.
emplace_back
유형의 인수를 가져서는 안되며 vector::value_type
대신 추가 된 항목의 생성자에 전달되는 가변 인수를 사용합니다.
template <class... Args> void emplace_back(Args&&... args);
전달하는 것이 가능하다 value_type
복사 생성자로 전달 될있다.
인수를 전달하기 때문에 이는 rvalue가없는 경우 컨테이너가 이동 된 복사본이 아닌 "복사 된"복사본을 저장한다는 것을 의미합니다.
std::vector<std::string> vec;
vec.emplace_back(std::string("Hello")); // moves
std::string s;
vec.emplace_back(s); //copies
그러나 위의 내용은하는 것과 동일해야합니다 push_back
. 아마도 다음과 같은 사용 사례를위한 것입니다.
std::vector<std::pair<std::string, std::string> > vec;
vec.emplace_back(std::string("Hello"), std::string("world"));
// should end up invoking this constructor:
//template<class U, class V> pair(U&& x, V&& y);
//without making any copies of the strings
에 대한 최적화 emplace_back
는 다음 예에서 설명 할 수 있습니다.
For emplace_back
constructor A (int x_arg)
will be called. And for push_back
A (int x_arg)
is called first and move A (A &&rhs)
is called afterwards.
Of course, the constructor has to be marked as explicit
, but for current example is good to remove explicitness.
#include <iostream>
#include <vector>
class A
{
public:
A (int x_arg) : x (x_arg) { std::cout << "A (x_arg)\n"; }
A () { x = 0; std::cout << "A ()\n"; }
A (const A &rhs) noexcept { x = rhs.x; std::cout << "A (A &)\n"; }
A (A &&rhs) noexcept { x = rhs.x; std::cout << "A (A &&)\n"; }
private:
int x;
};
int main ()
{
{
std::vector<A> a;
std::cout << "call emplace_back:\n";
a.emplace_back (0);
}
{
std::vector<A> a;
std::cout << "call push_back:\n";
a.push_back (1);
}
return 0;
}
output:
call emplace_back:
A (x_arg)
call push_back:
A (x_arg)
A (A &&)
emplace_back
conforming implementation will forward arguments to the vector<Object>::value_type
constructor when added to the vector. I recall Visual Studio didn't support variadic templates, but with variadic templates will be supported in Visual Studio 2013 RC, so I guess a conforming signature will be added.
With emplace_back
, if you forward the arguments directly to vector<Object>::value_type
constructor, you don't need a type to be movable or copyable for emplace_back
function, strictly speaking. In the vector<NonCopyableNonMovableObject>
case, this is not useful, since vector<Object>::value_type
needs a copyable or movable type to grow.
But note that this could be useful for std::map<Key, NonCopyableNonMovableObject>
, since once you allocate an entry in the map, it doesn't need to be moved or copied ever anymore, unlike with vector
, meaning that you can use std::map
effectively with a mapped type that is neither copyable nor movable.
A nice code for the push_back and emplace_back is shown here.
http://en.cppreference.com/w/cpp/container/vector/emplace_back
You can see the move operation on push_back and not on emplace_back.
One more in case of lists:
// constructs the elements in place.
emplace_back("element");
//It will create new object and then copy(or move) its value of arguments.
push_back(explicitDataType{"element"});
참고URL : https://stackoverflow.com/questions/4303513/push-back-vs-emplace-back
'Programing' 카테고리의 다른 글
dict.items ()와 dict.iteritems ()의 차이점은 무엇입니까? (0) | 2020.10.02 |
---|---|
오류 발생 : pgsql이 rails와 함께 작동하도록 시도 할 때 "postgres"사용자에 대한 피어 인증에 실패했습니다. (0) | 2020.10.02 |
Emacs와 Vim의 차이점 (0) | 2020.10.02 |
HTML에서 ID와 이름 속성의 차이점 (0) | 2020.10.02 |
동일한 catch 절에서 여러 Java 예외를 포착 할 수 있습니까? (0) | 2020.10.02 |