Шаблон функции с типом возврата T не компилируется - PullRequest
5 голосов
/ 15 марта 2011

Следующий код прекрасно компилируется:

template<typename T>
void f(const T &item) { return; }

int main() 
{
  f("const string literal");
}

Компиляция в ideone выполнена успешно: http://ideone.com/dR6iZ

Но когда я упоминаю тип возвращаемого значения, он не компилируется:

template<typename T>
T f(const T &item) { return item; }

int main() 
{
  f("const string literal");
}

Теперь выдает ошибку:

prog.cpp: 6: ошибка: не соответствует функция для вызова to f (const char [21]) ’

Код в ideone: http://ideone.com/b9aSb

Даже если я сделаю тип возврата const T, он не скомпилируется .

Мой вопрос:

  • Почему он не компилируется?
  • Как возвращаемый тип связан с ошибкой и созданием шаблона функции?

Ответы [ 2 ]

14 голосов
/ 15 марта 2011

Вы не можете вернуть массив из функции, поэтому создание экземпляра шаблона завершается неудачно, и нет соответствующей функции.

Вы получаете эту конкретную ошибку из-за SFINAE - Это на самом деле не ошибка, чтокомпилятор не может создать экземпляр вашей функции, он является ошибкой из-за отсутствия соответствующей функции.

Вы можете вернуть ссылку на массив - возврат T const & будет работать.

РЕДАКТИРОВАТЬ: В ответ на комментарии:

Во-первых, это на самом деле хороший пример SFINAE.

template<typename T> T f(const T &item) { return item; }
char const * f(void const * item) { return 0; }
int main() {
  f("abc");
}

Когда компилятор это компилирует, он сначалапопытайтесь создать экземпляр шаблона f, чтобы создать точное совпадение для типа const char [3].Это не удается по указанным причинам.Затем он выберет неточное совпадение, обычную функцию и при вызове затухает от const char [3] до const char *.

0 голосов
/ 15 марта 2011

похоже, вы говорите, что планируете вернуть T, но затем вы на самом деле возвращаете const T &. возможно попробуйте изменить объявление на:

template<typename T>
const T& f(const T& item) { return item; }

или, возможно, измените возвращаемое значение на разыменованную версию аргумента:

template<typename T>
T f(const T& item) { return (*item); }
...