Неявные параметры шаблона
Следующий код генерирует ошибку компиляции в Xcode:
template <typename T>
struct Foo
{
Foo(T Value)
{
}
};
int main()
{
Foo MyFoo(123);
return 0;
}
error: missing template arguments before 'MyFoo'
Изменение Foo MyFoo(123);
до Foo<int> MyFoo(123);
устраняет проблему, но не должен ли компилятор определить соответствующий тип данных?
Является ли это ошибкой компилятора, или я не понимаю неявные параметры шаблона?
Ответы
Ответ 1
Конструктор может теоретически вывести тип объекта, который он строит, но утверждение:
Foo MyFoo(123);
Выделяет временное пространство для MyFoo
и должен знать полностью определенный тип MyFoo
, чтобы узнать, сколько места необходимо.
Если вы хотите избежать ввода (т.е. пальцами) имени особо сложного шаблона, рассмотрите возможность использования typedef
:
typedef std::map<int, std::string> StringMap;
Или в С++ 0x вы можете использовать ключевое слово auto
, чтобы использовать вывод типа компилятора, хотя многие утверждают, что это приводит к менее читабельному и более подверженному ошибкам коду, и я сам среди них.; Р
Ответ 2
компилятор может определить тип параметра шаблона только для шаблонных функций, а не для классов/структур
Ответ 3
Это не ошибка, это несуществующая функция. Вы должны полностью указать аргументы шаблона класса/структуры во время создания экземпляра, всегда, типы не выводятся, поскольку они могут быть для шаблонов функций.
Ответ 4
Компилятор может вывести аргумент шаблона в таком случае:
template<typename T>
void fun(T param)
{
//code...
}
fun(100); //T is deduced as int;
fun(100.0); //T is deduced as double
fun(100.0f); //T is deduced as float
Foo<int> foo(100);
fun(foo); //T is deduced as Foo<int>;
Foo<char> bar('A');
fun(bar); //T is deduced as Foo<char>;
На самом деле аргумент шаблона аргумента является огромной темой. Прочтите эту статью в ACCU:
Вывод аргумента шаблона С++
Ответ 5
В С++ 11 вы можете использовать decltype
:
int myint = 123;
Foo<decltype(myint)> MyFoo(myint);
Ответ 6
Это имеет большое значение, так как Foo не является классом, только Foo<T>
, где T является типом.
В С++ 0x вы можете использовать auto, и вы можете создать функцию, чтобы сделать Foo, позвольте ей foo (нижний регистр f). Тогда вы бы сделали
template<typename T> Foo<T> foo(int x)
{
return Foo<T>(x);
}
auto myFoo = foo(55);
Ответ 7
То, что вы пытаетесь сделать, теперь работает в C++ 17. Параметры шаблона могут быть выведены в C++ 17.
template <typename T>
struct Foo
{
Foo(T Value)
{
}
};
int main()
{
Foo a(123);
Foo b = 123;
Foo c {123};
return 0;
}