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

linking static template variable

P: n/a
// - in my xy.cpp file --

template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
static const int varying_count = Ttex*2 + Tcol*3 + Tlight;
};

....
template<const int MyFragmentShader<0,1,0,1>::varying_count;
....
void foo()
{
// 'r' is of type super_complicated_class
r.fragment_shader<MyFragmentShader<0,1,0,1();
}
// -- ends

The result is:

undefined reference to `MyFragmentShader<0, 1, 0, 1>::varying_count'

I (try to) use GCC 4.0.2.

Can you please assist me?
Jan 2 '08 #1
Share this Question
Share on Google+
5 Replies


P: n/a
On 2 ÑÎ×, 19:42, "Gernot Frisch" <M...@Privacy.netwrote:
// - in my xy.cpp file --

template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
šstatic const int varying_count = Ttex*2 + Tcol*3 + Tlight;

};

...
template<const int MyFragmentShader<0,1,0,1>::varying_count;
...

void foo()
{
š š// 'r' is of type super_complicated_class
š šr.fragment_shader<MyFragmentShader<0,1,0,1();}

// -- ends

The result is:

undefined reference to `MyFragmentShader<0, 1, 0, 1>::varying_count'

I (try to) use GCC 4.0.2.

Can you please assist me?
(Warning! Highly unreliable opinion!) well, you haven't defined value
of that specialized constant (if this way of template specialization
is ever correct), you only have declared it, so linker doesn't find it.
Jan 2 '08 #2

P: n/a
(Warning! Highly unreliable opinion!) well, you haven't defined
value
of that specialized constant (if this way of template specialization
is ever correct), you only have declared it, so linker doesn't find
it.

// code----------
template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
static const int varying_count = Ttex*2 + Tcol*3 + Tlight;
};

#define VARCNT(t,c,l) template<const int
MyVertexShader<1,1,1>::attribute_count= t*2 + c*3 + l;
VARCNT(1,1,1);
VARCNT(1,1,0);
VARCNT(1,0,1);
VARCNT(1,0,0);
VARCNT(0,1,1);
VARCNT(0,1,0);
VARCNT(0,0,1);
VARCNT(0,0,0);
#undef VARCNT
// -------ends

yields:
error: duplicate initialization of MyVertexShader<1, 1,
1>::attribute_count

....I'm so, so lost here.
Jan 2 '08 #3

P: n/a
Gernot Frisch wrote:
>(Warning! Highly unreliable opinion!) well, you haven't defined
value
of that specialized constant (if this way of template specialization
is ever correct), you only have declared it, so linker doesn't find
it.


// code----------
template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
static const int varying_count = Ttex*2 + Tcol*3 + Tlight;
};

#define VARCNT(t,c,l) template<const int
MyVertexShader<1,1,1>::attribute_count= t*2 + c*3 + l;
So, is it 'varying_count' or 'attribute_count'?
VARCNT(1,1,1);
VARCNT(1,1,0);
VARCNT(1,0,1);
VARCNT(1,0,0);
VARCNT(0,1,1);
VARCNT(0,1,0);
VARCNT(0,0,1);
VARCNT(0,0,0);
#undef VARCNT
// -------ends

yields:
error: duplicate initialization of MyVertexShader<1, 1,
1>::attribute_count

...I'm so, so lost here.
Since you have the initialisation in the declaration (in the
class template definition), you should omit any initialisation
when defining your specialisations. That's what the compiler
is telling you here.

However, going back to your original inquiry, you need to use
your static somehow to cause the _instantiation_ of the static
member. It is likely that you didn't (at least the code you
posted didn't show any *use* of varying_count'.

Perhaps you want to repost *the actual code* that exhibits the
error...

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

P: n/a

Found it, sorry for bothering!

#define VARCNT(t,c,l) \
template<const int \
MyVertexShader<\
/* here is the bug */ \
t,c,l /* instead of 1,1,1! */ \
>::attribute_count= t*2 + c*3 + l;
and one must not define the value in the declaration, then.

template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
static const int varying_count; // = Ttex*2 + Tcol*3 + Tlight;
};
Jan 2 '08 #5

P: n/a
On Jan 2, 4:54 pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Gernot Frisch wrote:
(Warning! Highly unreliable opinion!) well, you haven't
defined value of that specialized constant (if this way of
template specialization is ever correct), you only have
declared it, so linker doesn't find it.
I think that's actually correct.
// code----------
template
<const int Ttex, const int Tcol, const int Tlight, int TzBuffer>
struct MyFragmentShader
{
static const int varying_count = Ttex*2 + Tcol*3 + Tlight;
};
#define VARCNT(t,c,l) template<const int
MyVertexShader<1,1,1>::attribute_count= t*2 + c*3 + l;
So, is it 'varying_count' or 'attribute_count'?
Different class template (MyVertexShader, instead of
MyFragmentShader), so why not a different name for the static.
I think he's just trying to confuse us by showing parts of two
different classes.

And is there an initializer or not in the explicit
specialization? That's very important, because as in the
original posting:
template<const int MyFragmentShader<0,1,0,1>::varying_count;
without the initializer, this is a *declaration* of a
specialization. And as you know, an explicit specialization is
*not* a template, per se, and obeys the usual rules of
non-template declarations. Which means that if he uses it,
there'd better be one (and only one) definition in the program.
Somewhere, in a source file (not in the header), a
template<const int
MyFragmentShader<0,1,0,1>::varying_count = something ;
VARCNT(1,1,1);
VARCNT(1,1,0);
VARCNT(1,0,1);
VARCNT(1,0,0);
VARCNT(0,1,1);
VARCNT(0,1,0);
VARCNT(0,0,1);
VARCNT(0,0,0);
#undef VARCNT
// -------ends
yields:
error: duplicate initialization of MyVertexShader<1, 1,
1>::attribute_count
...I'm so, so lost here.
What's to be lost about. You explicitely specialize
MyVertexShader<1,1,1>::attribute_count 8 times, with different
initializers.

Again, an explicit specialization behaves pretty much like a
normal declaration. You wouldn't expect something like:

int const SomeClass::foo = 1*2 + 1*3 + 1 ;
int const SomeClass::foo = 1*2 + 1*3 + 0 ;
int const SomeClass::foo = 1*2 + 0*3 + 1 ;
int const SomeClass::foo = 1*2 + 0*3 + 0 ;
int const SomeClass::foo = 0*2 + 1*3 + 1 ;
int const SomeClass::foo = 0*2 + 1*3 + 0 ;
int const SomeClass::foo = 0*2 + 0*3 + 1 ;
int const SomeClass::foo = 0*2 + 0*3 + 0 ;

to work, and what you've written is basically the same thing.

I suspect a typo in the macro, and what you meant was:
#define VARCNT(t,c,l) template<const int \
MyVertexShader<t,c,l>::attribute_count= t*2 + c*3 + l;
But beware: this still generates a *definition*, and not just a
declaration. Invoke your series of VARCNT in a header file,
include the header in more than one translation unit, and you'll
have multiple definitions (which the compiler isn't required to
diagnose).
Since you have the initialisation in the declaration (in the
class template definition), you should omit any initialisation
when defining your specialisations.
No. An explicit specialization replaces the template code. I
think he's confused you with his mixing two different classes
and two different problems in the same posting.
That's what the compiler is telling you here.
However, going back to your original inquiry, you need to use
your static somehow to cause the _instantiation_ of the static
member. It is likely that you didn't (at least the code you
posted didn't show any *use* of varying_count'.
If the static wasn't used, he wouldn't get an undefined
reference. The problem is that it is used, but he's explicitly
told the compiler not to instantiate the template variant,
becvause he's providing this one himself.
Perhaps you want to repost *the actual code* that exhibits the
error...
That would be nice. Preferrably in two separate postings, one
for each error.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Jan 2 '08 #6

This discussion thread is closed

Replies have been disabled for this discussion.