2016-04-15 2 views
0

Этот код компилируется (Visual Studio 2013). Обратите внимание, что я передаю в Set, а не Set<T>, как параметр operator =, в тело функции, которое находится за пределами определения класса. Но я не могу вернуть Set или его член Set; он должен вернуть Set<T> и быть членом Set<T>.В классе функций класса членов класса вне определения класса, когда требуются параметры шаблона?

Где законно оставлять параметры шаблона? Inside the class definition, а где еще?

Это изменение в стандарте? Я пытаюсь поддерживать совместимость со всеми существующими версиями, в том числе 98.

template <typename T> 
class Set 
{ 
public: 
    Set() {}   

    const Set& operator=(const Set& rhs); 
    //Shouldn't this have to be 
    //const Set<T>& operator= (const Set<T>& rhs); ? 

}; 

template <typename T> 
const Set<T>& Set<T>::operator= (const Set& rhs) //<-- HERE 
{ 
    Set temp;         //<-- AND HERE 
    /* ... */ 
    return *this; 
} 

int main() 
{ 
    Set<int> S, T; 
    T = S; 
} 
+0

AFAIK только классы делают это, так как они имеют нагнетаемого классовое имя – NathanOliver

+0

и здесь: 'шаблон auto Set :: operator = (const Set &) -> const Set & ' –

+0

' void main' недействителен и помешало бы многим (большинству) читателям попробовать ваш код. Я это исправил. Пожалуйста, не отправляйте код с 'void main', если вопрос об этом конкретно не упоминается, поскольку он вводит в заблуждение читателей новичков и делает невозможным просто копировать и вставлять код, чтобы попробовать, если только один из них не использует один из немногих компиляторов которые принимают его. –

ответ

0

Имя класса предоставляется в классе. И в отдельном определении члена, как только вы передадите спецификацию типа возвращаемого кода C++ 03 и имя функции, вы находитесь в классе. Таким образом, это нормально в C++ 03:

template< class T > 
Set<T> const& Set<T>::operator=(Set const& rhs) 

И это нормально в C++ 11:

template< class T > 
auto Set<T>::operator=(Set const& rhs) -> Set const& 

Это на самом деле не имеет ничего общего с шаблонами, но он связан с доступом к имени, доступному в классе.

Например, в C++ 03 вы должны написать

struct S 
{ 
    struct Inner {}; 
    Inner foo(); 
}; 

S::Inner S::foo() { return Inner(); } 

в то время как с C++ 11 и более поздних версий вы можете написать

struct S 
{ 
    struct Inner {}; 
    auto foo() -> Inner; 
}; 

auto S::foo() -> Inner { return {}; } 

что одна хорошая причина, в том числе многие другие, чтобы использовать синтаксис типа возвращаемого типа в качестве единственного соглашения о синтаксисе.


This не в норме в С или C++, независимо от того, какой году стандарт:

void main() //! NOT VALID. 
+0

Знаете ли вы, что то, что у вас здесь, также действует на C++ 98? –

+0

Код C++ 03 действителен с компилятором C++ 98. Единственной новой функцией, введенной в C++ 03, была инициализация значений. C++ 03 был всего лишь * техническим исправлением * C++ 98, называемым TC1 в то время (это было первое и единственное). –

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