Я использую std::make_pair()
для этого примера, потому что практически любой программист C ++ должен быть знаком с ним, но в целом мне интересно узнать о шаблоне, который он использует.
Мне пришло в голову, чтоХотя мне нравится удобство std::make_pair()
, он создает «лишнюю» копию каждого аргумента, поскольку создает пару и возвращает ее по значению.Если я затем использую это для вставки в контейнер STL, это означает, что фактически каждый параметр копируется в общей сложности 3 раза ... Я написал этот фрагмент кода для иллюстрации (наряду с некоторыми попытками улучшить его, не теряя слишком большого удобства):
#include <iostream>
#include <utility>
#include <list>
using namespace std;
// C++11 only:
#define MAKE_PAIR(a,b) pair<decltype(a),decltype(b)>((a),(b))
class A {
public:
A () { }
A (const A& a) {
cout << "\tCopy constructor called" << endl;
}
};
int main()
{
list<pair<int,A> > l;
cout << "Using std::make_pair()" << endl;
l.push_back(make_pair(10,A()));
cout << "Using MAKE_PAIR()" << endl;
l.push_back(MAKE_PAIR(10,A()));
typedef pair<int, A> my_pair;
cout << "Using a typedef" << endl;
l.push_back(my_pair(10,A()));
}
, который производит вывод:
Using std::make_pair()
Copy constructor called
Copy constructor called
Copy constructor called
Using MAKE_PAIR()
Copy constructor called
Copy constructor called
Using a typedef
Copy constructor called
Copy constructor called
Я понимаю, что здесь есть пара других копий, которые, вероятно, могут быть удалены (или, скорее, сокращены до копий указателя / интеллектуального указателя), напримериспользуя вместо этого A * или умный указатель в паре и выделяя его сам.
Идея макроса (для которой требуется C ++ 11) показалась мне интересной, хотя я знаю, что многие не любят макросы.Typedef тоже работает нормально, но тогда вам нужно создать отдельную typedef для каждого набора аргументов шаблона, и поэтому это удобнее, чем указывать аргументы шаблона явно каждый раз, но все же не так хорошо, как функция-обертка.
Мне интересно, кто-нибудь на самом деле избегает make_pair()
на практике по этой причине?Предлагает ли C ++ / C ++ 11 какие-либо другие интересные решения?
Мне нравится эта идея создания шаблонной обёртки функции вокруг конструктора, чтобы мы могли выводить аргументы шаблона, но я не настолько без ума отвоздействие во время выполнения из-за этого.