Разница при пропуске списка аргументов шаблона C++

Когда вы можете опустить список аргументов шаблона C++? Например, в Visual Studio 2010 этот фрагмент кода компилируется нормально:

template<class T>
Vec2<T> Vec2<T>::operator+ (const Vec2 &v) const
{
    return Vec2(x + v.x, y + v.y);
}

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

template<class T>
Vec2<T> Vec2<T>::operator+ (const Vec2<T> &v) const
{
    return Vec2<T>(x + v.x, y + v.y);
}

person George    schedule 11.09.2010    source источник


Ответы (1)


Внутри класса вы можете опустить аргумент типа класса:

template<typename K>
struct A {
   A<K> foo1; // legal
   A foo2; // also legal and identical to A<K> foo
   A bar(A x) {...} // same as A<K> bar(A<K> x) {...}
};

Вне области класса вам нужны аргументы шаблона:

// legal
template<typename K>
A<K> foo(A<K> x) { return A<K>(); }

// illegal!
template<typename K>
A foo(A x) { return A(); }

Если вы объявляете функцию-член вне класса, вам нужен список шаблонов для типа возвращаемого значения и для класса:

// legal
template<typename K>
A<K> A<K>::bar(A<K> x) { return A<K>(x); }

// legal
template<typename K>
A<K> A<K>::bar(A x) { return A(x); }

// illegal!
template<typename K>
A A::bar(A<K> x) { return A<K>(x); }
person Danvil    schedule 11.09.2010
comment
Итак, я думаю, даже несмотря на то, что первая версия компилируется без использования аргумента везде, вероятно, это хороший стиль - использовать его везде при объявлении/определении функции-члена вне класса. Спасибо! - person George; 11.09.2010
comment
Я что-то пропустил. Итак, короткий ответ: ваши две версии идентичны. - person Danvil; 11.09.2010
comment
Я искал ответ на cppreference.com, прежде чем найти этот вопрос/ответ, но ничего не нашел. Этого просто нет на сайте или я проглядел? В частности меня интересует техническая причина. Типа: список параметров оценивается в рамках созданного класса (поэтому A = A<K>), а возвращаемое значение — нет. (Что кажется непоследовательным, потому что оба составляют сигнатуру метода, не так ли?) - person Martin Nyolt; 19.07.2015