C++ make_pair vs {}

서론
C++ 에서 정렬이 필요한 container용으로 pair를 주로 사용하는 편인데 평소 이것들을 넣을 때 make_pair 를 통해서 넣어주고 있었습니다. 그런데 다른 분드르이 코드를 보면 { } 안에 원소들을 넣어서 코드가 더 짧아보이는 일이 있었습니다. 평소에는 'make_pair이 최적화가 더 잘 되지 않을까?' 하는 생각에 계속 이를 사용했는데 이번에는 정확히 어떤 차이가 있는지 알아보도록 하겠습니다.
make_pair vs std::pair
일단 넣는데 make_pair과 std::pair를 사용하는 방법이 있습니다.
#include <vector>
std::vector<std::pair<int, int>> vec;
int main(){
vec.push_back(std::make_pair(1, 2));
vec.push_back(std::pair<int, int>(1, 2));
}
std::make_pair의 경우 인자들의 타입을 자동으로 매칭해 주지만 std::pair를 사용하는 경우 넣을 때마다 인자의 타입을 명시해줘야 한다는 단점이 있습니다. 이는 make_pair가 템플릿으로 되어 있어서 그렇습니다.
// C++ 11
template< class T1, class T2 >
std::pair<T1,T2> make_pair( T1 t, T2 u );
// C++ 14
template< class T1, class T2 >
constexpr std::pair<V1,V2> make_pair( T1&& t, T2&& u );
make_pair vs { } (Curly Brackets)
#include <vector>
std::vector<std::pair<int, int>> vec;
int main(){
vec.push_back({1, 2});
}
일단 위 { }를 사용하면 make_pair보다 훨씬 가독성이 좋아집니다. 그런데 중요한점은 성능상 큰 차이가 없냐 였습니다. 그래서 여기저기 본 결과 어디선가 어셈블리 코드를 구할 수 있었습니다.
// make_pair
mov eax, DWORD PTR x[rip]
lea rsi, [rsp+24]
mov DWORD PTR [rsp+24], eax
mov eax, DWORD PTR y[rip]
mov DWORD PTR [rsp+28], eax
// { }
mov eax, DWORD PTR x[rip]
lea rsi, [rsp+24]
mov edi, OFFSET FLAT:vec
mov DWORD PTR [rsp+24], eax
mov eax, DWORD PTR y[rip]
mov DWORD PTR [rsp+28], eax
edi 레지스터(메모리 주소를 알아내는 용도로 EBX 레지스터의 일부)에 offset을 더하는 코드가 더 있을 뿐 어셈블리 단에서 큰 차이가 없었습니다.
비교 연산 == 에서
pair<T1, T2> 자료구조에 대한 비교가 필요한 때가 있습니다. 이때 C++17의 컴파일러와 이전의 컴파일러에 따라 코드가 달라지게 됩니다.
#include <vector>
std::pair<int, int> p;
int main(){
p = {1, 2};
if(p ==std::pair{1, 2}){
// C++ 17
}
if(p == std::make_pair(1, 2)){
// C++ 14
}
}
제가 가진 GCC 버전은 6.3.0 인데 17 버전을 지원해주지 않는지 위 std::pair{1, 2} 와의 비교가 불가능했습니다. 컴파일러 버전을 잘 체크해야 될 것 같네요.
참고 출처
- make_pair vs { } assembly
Difference between make_pair and curly brackets { } for assigning a pair in C++?
I didn't find anyone answering this, is there any difference between the following : v.push_back({x, y}); and : v.push_back(make_pair(x, y)); Assuming that v was declared this way : vector&l...
stackoverflow.com
- make_pair 템플릿 코드
std::make_pair - cppreference.com
template< class T1, class T2 > std::pair make_pair( T1 t, T2 u ); (until C++11) template< class T1, class T2 > std::pair make_pair( T1&& t, T2&& u ); (since C++11) (until C++14) template< class T1, class T2 > constexpr std::pair make_pair( T1&& t, T2&& u )
en.cppreference.com
- pair == operator
Pair and curly brace check
#include <bits/stdc++.h> using namespace std; int main() { pair<int,int>p = {1,3}; if (p=={1,3}) cout << "yeyey\n"; } I want to check whether this pai...
stackoverflow.com