By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,200 Members | 1,584 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,200 IT Pros & Developers. It's quick & easy.

Static variable in class template - multiple definition

P: n/a
Hel
Hi,

I'm sure you are familiar with this problem:

A.h:

template <unsigned Nstruct A {
static const unsigned a;
};

template <const unsigned A<0>::a = 1;
template <unsigned Nconst unsigned A<N>::a = A<N-1>::a*N;

Now if I include A.h from multiple .cpp files I get a linking error
because A<Nhas multiple definitions. Easy solution there, move the
definitions to A.cpp and just include A.h. BUT:

B.h:

#include "A.h"

template <unsigned Mclass B {
int b[A<M>::a];
};

This only works if the compiler has seen the definition of A<N>::a. (g+
+ 4.2 says "array bound is not an integer constant".)

I can't wrap my head around this one. I need the declaration for B<M>
in many .cpp files, and I need to calculate A<M>::a in the declaration
of B (in fact, not to define the size of the array, but as another
template parameter - so dynamic allocation is not an option. The
template definition is left out for brevity's sake.)

TIA

Helge
Jun 27 '08 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Hel wrote:
Hi,

I'm sure you are familiar with this problem:

A.h:

template <unsigned Nstruct A {
static const unsigned a;
};

template <const unsigned A<0>::a = 1;
template <unsigned Nconst unsigned A<N>::a = A<N-1>::a*N;

Now if I include A.h from multiple .cpp files I get a linking error
because A<Nhas multiple definitions. Easy solution there, move the
definitions to A.cpp and just include A.h. BUT:

B.h:

#include "A.h"

template <unsigned Mclass B {
int b[A<M>::a];
};

This only works if the compiler has seen the definition of A<N>::a. (g+
+ 4.2 says "array bound is not an integer constant".)

I can't wrap my head around this one. I need the declaration for B<M>
in many .cpp files, and I need to calculate A<M>::a in the declaration
of B (in fact, not to define the size of the array, but as another
template parameter - so dynamic allocation is not an option. The
template definition is left out for brevity's sake.)
Since it's a static integral constant, you can simply initialise it in
the class itself:

template <unsigned Nstruct A {
static const unsigned a = A<N-1>::a * N;
};

And specialise the whole class instead of defining the member in the
header...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 27 '08 #2

P: n/a
Hel wrote:
Hi,

I'm sure you are familiar with this problem:

A.h:

template <unsigned Nstruct A {
static const unsigned a;
};

template <const unsigned A<0>::a = 1;
template <unsigned Nconst unsigned A<N>::a = A<N-1>::a*N;

Now if I include A.h from multiple .cpp files I get a linking error
because A<Nhas multiple definitions.
Because A<0>::a has multiple definitions actually. Try just moving that
one.

BTW, you might consider an alternative design, since you are dealing
with integral values:

template < unsigned N >
struct A
{
enum { a = A<N-1>::a * N };
};

template <>
struct A<0>
{
enum { a = 1 };
};

Numerous benefits here. For instance, I don't believe any of the A
objects are actually instantiated and therefore, unlike your static int
version that will instantiate all in between, there is only one static
value that is generated by the metaprogram.
Jun 27 '08 #3

This discussion thread is closed

Replies have been disabled for this discussion.