Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > linking static template variable

Reply
Thread Tools

linking static template variable

 
 
Gernot Frisch
Guest
Posts: n/a
 
      01-02-2008
// - 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?


 
Reply With Quote
 
 
 
 
Pavel Shved
Guest
Posts: n/a
 
      01-02-2008
On 2 ÑÎ×, 19:42, "Gernot Frisch" <(E-Mail Removed)> wrote:
> // - 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.
 
Reply With Quote
 
 
 
 
Gernot Frisch
Guest
Posts: n/a
 
      01-02-2008

> (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.


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      01-02-2008
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


 
Reply With Quote
 
Gernot Frisch
Guest
Posts: n/a
 
      01-02-2008

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;
};


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      01-02-2008
On Jan 2, 4:54 pm, "Victor Bazarov" <(E-Mail Removed)> wrote:
> 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:(E-Mail Removed)
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Linking to a global variable in a static library fails Jaco Naude C++ 1 07-25-2008 12:52 PM
non-static variable this cannot be referenced from a static context kookey Java 3 08-20-2005 07:43 PM
Linking static library including template Roland Raschke C++ 1 09-22-2003 07:02 PM
Global static variable vs static method Marcin Vorbrodt C++ 3 09-05-2003 07:52 AM
a static local variable in a static method is thread local storage? Patrick Hoffmann C++ 3 08-08-2003 02:37 PM



Advertisments