initialization of a static member of a template class

R

Ralf Goertz

Hi,

I'm not sure whether this only applies to template classes but that's
where I stumbled over it.

Usually I try to inizialize variables not by assignment but by ctor,
i.e. "int i(0)" instead of "int i=0". But this doesn't work in the
following code:

#include <functional>

using namespace std;

template<class T> struct Odd : public unary_function<T,bool> {
bool operator() (T i) const {
return i%2;
}
};

template<class T> class X {
static Odd<T> odd;
};

template<class T> Odd<T> X<T>::eek:dd(Odd<T>()); // (*)

int main() {
X<int> x;
Odd<long> odder(Odd<long>()); // (**)
return 0;
}


Comeau gives:

"ComeauTest.c", line 15: error: declaration is incompatible with "Odd<T>
X<T>::eek:dd"
(declared at line 12)
template<class T> Odd<T> X<T>::eek:dd(Odd<T>());
^

g++ gives:

x.cc:15: error: no ‘Odd<T> X<T>::eek:dd(Odd<T> (*)())’ member function declared in
class ‘X<T>’


If I replace (*) with

template<class T> Odd<T> X<T>::eek:dd=Odd<T>();

it works, which is even odder since the ctor construction works in the
line marked by (**). By the way, why is it necessary to have a static
member of a template initialized at all?
 
J

joseph cook

If I replace (*) with

template<class T> Odd<T> X<T>::eek:dd=Odd<T>();

it works, which is even odder since the ctor construction works in the
line marked by (**). By the way, why is it necessary to have a static
member of a template initialized at all?

Why not just
template<class T> Odd<T> X<T>::eek:dd ?

You just need to define the variable somewhere. The parser is
getting confused thinking that you are defining a new function as
opposed to calling the default constructor of Odd<T>

Joe
 
R

Ralf Goertz

joseph said:
Why not just
template<class T> Odd<T> X<T>::eek:dd ?

Yes, that works here. But what if I don't want the default ctor?
You just need to define the variable somewhere. The parser is
getting confused thinking that you are defining a new function as
opposed to calling the default constructor of Odd<T>

Hm, I figured that could be the problem. But that means that—strictly
speaking—it is not an error but the comiler is too stupid?
 
V

Vladimir Jovic

Ralf said:
Yes, that works here. But what if I don't want the default ctor?

Then you would pass the parameter(s), like this :
template<class T> Odd<T> X<T>::eek:dd( p1, p2 );
and not like this:
template<class T> Odd<T> X<T>::eek:dd( Odd<T>( p1, p2 ) );
 
R

Ralf Goertz

Vladimir said:
Then you would pass the parameter(s), like this :
template<class T> Odd<T> X<T>::eek:dd( p1, p2 );
and not like this:
template<class T> Odd<T> X<T>::eek:dd( Odd<T>( p1, p2 ) );

Ouch, of course, thanks.

Remains the question why it is necessary to have that initialization line.
 
J

James Kanze

Yes, that works here. But what if I don't want the default ctor?
Hm, I figured that could be the problem. But that means
that—strictly speaking—it is not an error but the comiler is
too stupid?

No. That means that the declaration grammar for C++ is
ambiguous, and that the standard says that in such cases, you've
just tried to declare a function. It's a well-known (and
frequent) problem, sometimes referred to as C++'s mosts
embaressing parse.

An extra set of parentheses will remove the ambiguity:

template< typename T > Odd<T> X<T>::eek:dd((Odd<T>()));
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,522
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top