의 목적은 std::make_pair
무엇입니까?
왜 안 해 std::pair<int, char>(0, 'a')
?
두 방법 사이에 차이점이 있습니까?
std::make_pair
중복입니다. 아래에 이것을 자세히 설명하는 답변이 있습니다.
의 목적은 std::make_pair
무엇입니까?
왜 안 해 std::pair<int, char>(0, 'a')
?
두 방법 사이에 차이점이 있습니까?
std::make_pair
중복입니다. 아래에 이것을 자세히 설명하는 답변이 있습니다.
답변:
차이점은 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)
당신이 하나를 할당 할 때마다, 그것은 시간이 지남에 성가신 것입니다 ...
one = {10, 20}
요즘에는 할 수 있다고 생각 하지만 확인하기에 편리한 C ++ 11 컴파일러는 없습니다.
make_pair
구조체, 공용체, 람다 및 기타 doodad를 포함하여 명명되지 않은 유형에서 작동합니다.
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로 테스트되었습니다 .
std::make_pair
-C ++ 17에서 더 이상 사용되지 않는 이유는 무엇 입니까?
make_pair
참조 랩퍼의 랩을 해제하므로 실제로 CTAD와 다릅니다.
지정된 형식 인수로 생성자를 사용 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);
}
&&
C ++ 11 이후 실제로 .
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;
}
std::move
내부 insert
및 / 또는 관련 내용이 있습니다 sample
. 내가 변경할 경우에만입니다 std::map<int,Sample>
에 std::map<int,Sample const&>
내가 구성 객체의 수를 줄일 것을, 오직 내가 모든 사본을 (분명히) 제거하는 복사 생성자를 삭제할 때. 두 가지 변경을 모두 한 후에는 기본 생성자에 대한 하나의 호출과 동일한 객체에 대한 소멸자에 대한 두 개의 호출이 포함됩니다. 뭔가 빠진 것 같아요. (g ++ 5.4.1, c ++ 11)
emplace
대신 insert
(추가 인스턴스를 원하지 않는 경우) 대신 권장 할 것입니다 . 전문가가 있다고 말할 수 있다면 내 전문 분야는 아니지만 복사 / 이동 C ++ 11에서 소개 한 시맨틱은 많은 도움이되었습니다.