std :: make_pair와 std :: pair의 생성자의 목적은 무엇입니까? 안 해 std::pair<int, char>(0, ‘a’)? 두 방법

의 목적은 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);
}

같은 개념이 insertervs에 적용됩니다 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::pairstd::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};