XYZ<temp> abc(temp());
Он компилируется, потому что это НЕ объявление переменной . Я уверен, что вы думаете, что это объявление переменной, когда дело в том, что это объявление function . Название функции: abc
; функция возвращает объект типа XYZ<temp>
и принимает один (неназванный) аргумент, который, в свою очередь, является функцией, возвращающей тип temp
и не принимающей аргумента. Смотрите эти темы для подробного объяснения:
И fun(temp())
не компилируется, потому что temp()
создает временный объект, и временный объект не может быть привязан к неконстантной ссылке.
Итак, исправление таково: определите шаблон вашей функции как:
template<typename T>
void fun(const T & arg) //note the `const`
{
}