Когда компилятор может вывести параметр шаблона?
Иногда это иногда срабатывает не:
template <class T>
void f(T t) {}
template <class T>
class MyClass {
public:
MyClass(T t) {}
};
void test () {
f<int>(5);
MyClass<int> mc(5);
f(5);
MyClass mc(5); // this doesn't work
}
Есть ли способ взломать пример выше? То есть заставить компилятор вывести параметр шаблона из параметра конструктора.
Будет ли это исправлено в будущем, или есть веская причина не для этого?
Каково общее правило, когда компилятор может вывести параметр шаблона?
Ответы
Ответ 1
Параметры шаблона могут быть выведены для шаблонов функций, когда тип параметра может быть выведен из параметров шаблона
Итак, это можно сделать здесь:
template <typename T>
void f(T t);
template <typename T>
void f(std::vector<T> v);
но не здесь:
template <typename T>
T f() {
return T();
}
И не в шаблонах классов.
Итак, обычное решение вашей проблемы - создать функцию-оболочку, аналогичную стандартной библиотечной функции std::make_pair
:
template <class T>
class MyClass {
public:
MyClass(T t) {}
void print(){
std::cout<<"try MyClass"<<std::endl;
}
};
template <typename T>
MyClass<T> MakeMyClass(T t) { return MyClass<T>(t); }
а затем вызовите auto a = MakeMyClass(5);
для создания экземпляра класса.
Ответ 2
Читайте на Дедукция аргумента шаблона (и Поиск ADL или Koenig).
Ответ 3
В C++ 17 можно вывести некоторые типы, используя auto
, хотя параметры шаблона все еще должны быть указаны здесь:
#include <iostream>
#include <string>
template <class T1,class T2>
auto print_stuff(T1 x, T2 y)
{
std::cout << x << std::endl;
std::cout << y << std::endl;
}
int main()
{
print_stuff(3,"Hello!");
print_stuff("Hello!",4);
return 0;
}
Используя флаг -fconcepts в gcc, можно опустить параметры типа, хотя это еще не является частью стандарта C++:
#include <iostream>
#include <string>
auto print_stuff(auto x, auto y)
{
std::cout << x << std::endl;
std::cout << y << std::endl;
}
int main()
{
print_stuff(3,"Hello!");
print_stuff("Hello!",4);
return 0;
}