Аргументы шаблона класса не могут быть выведены из конструктора до 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
против 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);
, которая использует обычную функцию вместо конструктора.
Протестировано с GCC 8.1.0, Ubuntu 16.04 .