Какова цель std::make pair против конструктора std:: pair?


какова цель std::make_pair?

почему бы просто не сделать std::pair<int, char>(0, 'a')?

есть ли разница между двумя методами?

6 128

6 ответов:

разница в том, что с 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};

нет никакой разницы между использованием 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++. Он известен как идиома генератора объектов, вы можете найти дополнительную информацию и хороший пример здесь.

Edit как кто-то предложил в комментариях (так как удалено) следующее-Это немного измененная выдержка из ссылки в случае ее разрыва.

генератор объектов позволяет создавать объекты без явного указания их типов. Он основан на полезном свойство шаблонов функций, которые не имеют шаблонов классов: параметры типа шаблона функции выводятся автоматически из его фактических параметров. std::make_pair простой пример, который возвращает экземпляр std::pair шаблон в зависимости от фактических параметров

аргументы шаблона класса не могут быть выведены из конструктора до 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};

повторяется типов, и может быть очень длинным.

вывод типа работает в этом случае до C++17, потому что make_pair - это не конструктор.

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.

Читайте также:

make_pair создает дополнительную копию над прямым конструктором. Я всегда typedef мои пары, чтобы обеспечить простой синтаксис.
Это показывает разницу (пример Рампала Чаудхари):

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;
}