의 목적은 std::make_pair
무엇입니까?
왜 안 해 std::pair<int, char>(0, 'a')
?
두 방법 사이에 차이점이 있습니까?
답변
차이점은 std::pair
두 요소의 유형을 지정 해야하는 반면, std::make_pair
전달 할 요소의 유형과 쌍을 만들지 않아도 말할 필요가 없다는 것입니다. 어쨌든 다양한 문서에서 수집 할 수있는 것입니다.
http://www.cplusplus.com/reference/std/utility/make_pair/ 에서이 예를 참조하십시오.
pair <int,int> one;
pair <int,int> two;
one = make_pair (10,20);
two = make_pair (10.5,'A'); // ok: implicit conversion from pair<double,char>
make_pair를 사용하지 않은 경우 암시 적 전환 보너스와는 별도로
one = pair<int,int>(10,20)
당신이 하나를 할당 할 때마다, 그것은 시간이 지남에 성가신 것입니다 …
답변
@MSalters가 위에서 대답했듯이 이제 중괄호를 사용하여 C ++ 11 에서이 작업을 수행 할 수 있습니다 (C ++ 11 컴파일러로 이것을 확인했습니다).
pair<int, int> p = {1, 2};
답변
C ++ 17 이전에 생성자에서 클래스 템플리트 인수를 유추 할 수 없습니다.
C ++ 17 이전에는 다음과 같은 것을 작성할 수 없었습니다.
std::pair p(1, 'a');
생성자 인수에서 템플릿 유형을 유추하기 때문입니다.
C ++ 17은 그 구문을 가능하게하고 따라서 make_pair
중복됩니다.
C ++ 17 이전에는 std::make_pair
덜 자세한 코드를 작성할 수있었습니다.
MyLongClassName1 o1;
MyLongClassName2 o2;
auto p = std::make_pair(o1, o2);
더 장황한 대신 :
std::pair<MyLongClassName1,MyLongClassName2> p{o1, o2};
유형을 반복하며 매우 길 수 있습니다.
make_pair
생성자가 아니기 때문에 C ++ 17 이전의 사례에서 형식 유추가 작동합니다 .
make_pair
본질적으로 다음과 같습니다.
template<class T1, class T2>
std::pair<T1, T2> my_make_pair(T1 t1, T2 t2) {
return std::pair<T1, T2>(t1, t2);
}
같은 개념이 inserter
vs에 적용됩니다 insert_iterator
.
또한보십시오:
최소 예
보다 구체적으로하기 위해 다음을 사용하여 문제를 최소한으로 관찰 할 수 있습니다.
main.cpp
template <class MyType>
struct MyClass {
MyType i;
MyClass(MyType i) : i(i) {}
};
template<class MyType>
MyClass<MyType> make_my_class(MyType i) {
return MyClass<MyType>(i);
}
int main() {
MyClass<int> my_class(1);
}
그때:
g++-8 -Wall -Wextra -Wpedantic -std=c++17 main.cpp
행복하게 컴파일하지만 :
g++-8 -Wall -Wextra -Wpedantic -std=c++14 main.cpp
실패 :
main.cpp: In function ‘int main()’:
main.cpp:13:13: error: missing template arguments before ‘my_class’
MyClass my_class(1);
^~~~~~~~
대신 작동해야합니다.
MyClass<int> my_class(1);
또는 도우미 :
auto my_class = make_my_class(1);
생성자 대신 일반 함수를 사용합니다.
`std :: reference_wrapper의 차이점
이 의견 은 생성자가 그렇지 않은 동안 std::make_pair
언 랩핑 std::reference_wrapper
을 언급 하므로 한 가지 차이점이 있습니다. TODO 예.
GCC 8.1.0, Ubuntu 16.04로 테스트되었습니다 .
답변
지정된 형식 인수로 생성자를 사용 make_pair
하고 명시 적으로 호출하는 것에는 차이가 없습니다 pair
. std::make_pair
템플릿 메소드는 주어진 매개 변수를 기반으로 유형을 공제하므로 유형이 상세 할 때 더 편리합니다. 예를 들어
std::vector< std::pair< std::vector<int>, std::vector<int> > > vecOfPair;
std::vector<int> emptyV;
// shorter
vecOfPair.push_back(std::make_pair(emptyV, emptyV));
// longer
vecOfPair.push_back(std::pair< std::vector<int>, std::vector<int> >(emptyV, emptyV));
답변
이것이 C ++ 템플릿 프로그래밍의 일반적인 관용구라는 점은 주목할 가치가 있습니다. Object Generator 관용구로 알려져 있으며 여기에서 자세한 정보와 좋은 예를 찾을 수 있습니다 .
편집 누군가가 의견에서 제안한 것처럼 (제거 된 이후) 다음은 링크가 끊어 질 때 약간 수정 된 링크입니다.
객체 생성기는 유형을 명시 적으로 지정하지 않고도 객체를 생성 할 수 있습니다. 클래스 템플릿에는없는 함수 템플릿의 유용한 속성을 기반으로합니다. 함수 템플릿의 유형 매개 변수는 실제 매개 변수에서 자동으로 추론됩니다. 함수 의 실제 매개 변수에 따라 템플리트 std::make_pair
의 인스턴스를 리턴하는 간단한 예제입니다 .std::pair
std::make_pair
template <class T, class U>
std::pair <T, U>
make_pair(T t, U u)
{
return std::pair <T, U> (t,u);
}
답변
make_pair는 직접 생성자 위에 추가 복사본을 만듭니다. 나는 항상 간단한 구문을 제공하기 위해 쌍을 typedef합니다.
이것은 차이를 보여줍니다 (Rampal Chaudhary의 예).
class Sample
{
static int _noOfObjects;
int _objectNo;
public:
Sample() :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside default constructor of object "<<_objectNo<<std::endl;
}
Sample( const Sample& sample) :
_objectNo( _noOfObjects++ )
{
std::cout<<"Inside copy constructor of object "<<_objectNo<<std::endl;
}
~Sample()
{
std::cout<<"Destroying object "<<_objectNo<<std::endl;
}
};
int Sample::_noOfObjects = 0;
int main(int argc, char* argv[])
{
Sample sample;
std::map<int,Sample> map;
map.insert( std::make_pair( 1, sample) );
//map.insert( std::pair<int,Sample>( 1, sample) );
return 0;
}
답변
c ++ 11부터는 쌍에 대해 균일 한 초기화를 사용하십시오. 따라서 대신 :
std::make_pair(1, 2);
또는
std::pair<int, int>(1, 2);
그냥 사용
{1, 2};