質問

I'm trying to define a template class with a static member such that each specialization of the template has its own static member. Furthermore, the static member is an object of the class itself (to be used as a sentinel for a linked list.) I'm not sure this can even be legally done in C++, but if so, I am thrashing about and not getting it done.

A small sample that demonstrates what I am trying to accomplish is:

template<class E> class LL {
    static LL<E>   l;
};

class A {
};

template<typename A>
typename <class A>LL LL<A>::l;

When I compile with g++ (version 4.8.1) It reports:

g++ -Wall -o t-static.o t-static.cpp
t-static.cpp:9:14: error: expected nested-name-specifier before ‘<’ token
     typename <class A>LL LL<A>::l;
              ^
t-static.cpp:9:14: error: expected unqualified-id before ‘<’ token

(error is on the list line in the file.)

I'm afraid I don't really understand the diagnostic nor typenames and have been flailing at this for a while now with the only result being that I can get different error messages. I've found a bunch of questions that deal with this but none has helped me find a solution.

As a final note, I hope the solution is not specific to a particular g++ version as the eventual target for this code is an Arduino which presently uses g++ v4.3.2 and which does not support C++11 (or does not use C++11.)

Thank you for your help.

役に立ちましたか?

解決

Trying to use static members in a class template will cause you some grief as you'll need to explicitly instantiated them. To quickly address the immediate question: you just need to use the correct syntax for the definition.

template <typename E>
static LL<E> LL<E>::l;

However, if the compiler ends up instantiating this data member in multiple translation units you'll get multiply defined symbols. For various reasons you are much better off nesting the object into a function and return a reference from there instead:

template <typename E>
class LL {
    static LL<E>& l();
    // ...
};

template <typename E>
LL<E>& LL<E>::l() { static LL<E> rc; return rc; }

That said, you should seek not to use any global object at all! They tend to cause lots of problems, even if their access is constrained to be done from a given class.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top