Неявные параметры шаблона

Следующий код генерирует ошибку компиляции в 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;
}