2015-05-23 3 views
1

Ниже приведены два примера кода. Первый определяет operator+() для шаблона класса Vector, а второй просто объявляет функцию, но перемещает определение функции вне тела класса. Первые результаты выборки в следующей ошибке:Функция друга, определенная внутри шаблона класса. Ошибка переопределения шаблона функции

main.cpp(4): error C2995: 
'Vector<L,T> operator +(const Vector<L,T> &,const Vector<L,T> &)' : 
function template has already been defined 

Вот мои вопросы:

  1. Почему два шаблонных конкретизация в основном() результате в функциональных ошибках шаблона переопределения? Основываясь на моем понимании, они должны приводить к уникальным экземплярам, ​​поскольку параметры шаблона различны.
  2. Как перемещение определения функции вне тела класса разрешает ошибку?

образец Ошибка:

template<int L, typename T> 
class Vector { 

    template<int L, typename T> friend 
    Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) { 
    return Vector<L, T>(); 
    } 

private: 
    T data[L]; 
}; 

int main() { 
    Vector<42, double> v42d; 
    Vector<24, int> v24i; 

    return 0; 
} 

Работа образца:

template<int L, typename T> 
class Vector { 

    template<int L, typename T> friend 
    Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs); 

private: 
    T data[L]; 
}; 

template<int L, typename T> 
Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) { 
    return Vector<L, T>(); 
} 

int main() { 
    Vector<42, double> v42d; 
    Vector<24, int> v24i; 

    return 0; 
} 
+2

Вы теневые параметры шаблона в обоих образцах. Это ваш настоящий код? – Columbo

+0

BTW, с фиксированной тень, clang принимает код и g ++ отклоняет его [Demo] (http://coliru.stacked-crooked.com/a/0046cac7d6f39125). – Jarod42

+0

@ Jarod42 Ошибка аналогична в MSVC2013, если явно указаны как переменные шаблона параметров, так и переменные шаблона возвращаемого типа. – xslr

ответ

3

типы шаблонов L и T уже известны, так что не нужно повторно. Фактически это делает для функции friend, заставляя их затмить те, которые определены для класса.

это фиксирует это:

template<int L, typename T> 
class Vector { 

    friend 
    Vector<L, T> operator+(const Vector<L, T>& lhs, const Vector<L, T>& rhs) { 
     return Vector<L, T>(); 
    } 

private: 
    T data[L]; 
}; 

что эквивалентно:

template<int L, typename T> 
class Vector { 

    friend 
    Vector operator+(const Vector& lhs, const Vector& rhs) { 
     return Vector(); 
    } 

private: 
    T data[L]; 
}; 
+1

Вы можете даже опустить ''. – Jarod42

+0

@ Jarod42 обновлен в ответ. Спасибо. –

Смежные вопросы