2

I'm currently refactoring some code using the C++11 Alias Template (aka. template<class A> using B = C<A>;), but clang complains when I try to use the alias to implement a constructor or an operator.

Relevant header file:

template<class C>
class CSTree {
public:
    class DepthIterator : public std::iterator<std::random_access_iterator_tag, C> {
        DepthIterator(const DepthIterator&);
        bool operator==(const DepthIterator&);
        //other members omitted
    }
    //other members omitted 
}

Relevant source file:

template<class C>
using DeIt = typename CSTree<C>::DepthIterator;

template<class C>
DeIt<C>::DepthIterator(const DepthIterator &rhs) { //Error here!
    //...
}

template<class C>
bool DeIt<C>::operator== (const DepthIterator &rhs) { //Error here!
    //...
}

Compiling with clang gives the following error:

src/CSTree.cpp:13:10: error: nested name specifier 'DeIt<C>::' for declaration does not refer into a class, class template or class template partial specialization
src/CSTree.cpp:18:15: error: nested name specifier 'DeIt<C>::' for declaration does not refer into a class, class template or class template partial specialization

My tries to search the internet did not lead to any clear material on this topic, so I'm wondering whether it is possible to implement operators and constructors on Alias Templates and if it is, any hint regarding where I am erring is greatly appreciated (I'm still pretty new to C++, so it might just be a really obnoxious mistake. In that case I beg your pardon in advance).

Ben Steffan
  • 45
  • 1
  • 2
  • 5
  • 4
    Unrelated to your *current* problem, but are you implementing a templated class in a *source file*? You might want to read ["Why can templates only be implemented in the header file?"](http://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Some programmer dude May 10 '16 at 14:49
  • Thanks, I didn't know about that! Still, I'd like my implementations to be separated from my definitions, so I'll probably go with one of the solutions in the post you linked. – Ben Steffan May 10 '16 at 14:53

1 Answers1

0

The alias can only be used when using the relevant class, not when defining it. So you should have:

template<class C>
CSTree<C>::DepthIterator::DepthIterator(const DepthIterator &rhs) {
     //...
}

template<class C>
bool CSTree<C>::DepthIterator::operator== (const DepthIterator &rhs) {
    //...
}

template<class C>
using DeIt = typename CSTree<C>::DepthIterator;
Smeeheey
  • 9,906
  • 23
  • 39
  • To be pedantic, OP isn't using the alias to define the *class*. They're using it to define the member functions of the class. Which indeed appears to not be allowed. – eerorika May 10 '16 at 15:05
  • @user2079303 - defining a class *is* defining its members, no? How is there a difference? – Smeeheey May 10 '16 at 15:09
  • This is declaration of a class: `struct A;` This a definition of a class: `struct A { /*member function declarations*/ };`. This is an out-of-line definition of a member function: `void A::foo() {}`. All definitions are also declarations. A class can be fully defined without defining any of it's member functions. – eerorika May 10 '16 at 15:14
  • @user2079303 - actually if we're being pedantic `struct A;` is a *forward* declaration of a class. What you specify as the definition of a class is actually the *declaration* according to [this](http://en.cppreference.com/w/cpp/language/class). An *out-of-line* member definition *is* part of the definition of the class – Smeeheey May 10 '16 at 15:20
  • Forward declarations are declarations. More specifically, they are declarations that are not definitions. The page that you linked doesn't back up your claim that member definitions are part of class definition. Since all definitions are also declarations (as I stated), it is technically true that what I specify as a definition is also a declaration. Note that the page that you linked seems to use both declaration and definition interchangeably... (see `struct s { char* p; }; // definitions of the local struct s`) which is probably a contributing factor to the confusion with their difference. – eerorika May 10 '16 at 15:27
  • @user2079303 - the only reason I made those references is to show that the pedantry can be turned on its head. I disagree with your initial comment that it is wrong to describe what is referenced above as "defining the class". I think "defining the class" is precisely what an *out-of-line* (or any other for that matter) member definition is doing. – Smeeheey May 10 '16 at 15:33
  • From a very abstract point of view, sure it is not wrong to consider the definition of the members to be part of the class "definition". That is why I qualified my comment as being pedantry. I think that the usage of the terms as they are used by official documents such as the standard is important in a question about whether particular syntax is correct in a language. My comment is for the benefit of readers who are not familiar with standard terminology and may be confused by your abstract usage. – eerorika May 10 '16 at 15:42