linking static template variable

Discussion in 'C++' started by Gernot Frisch, Jan 2, 2008.

  1. // - 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?
    Gernot Frisch, Jan 2, 2008
    #1
    1. Advertising

  2. Gernot Frisch

    Pavel Shved Guest

    On 2 ÑÎ×, 19:42, "Gernot Frisch" <> 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.
    Pavel Shved, Jan 2, 2008
    #2
    1. Advertising


  3. > (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.
    Gernot Frisch, Jan 2, 2008
    #3
  4. 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
    Victor Bazarov, Jan 2, 2008
    #4
  5. 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;
    };
    Gernot Frisch, Jan 2, 2008
    #5
  6. Gernot Frisch

    James Kanze Guest

    On Jan 2, 4:54 pm, "Victor Bazarov" <> 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:
    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
    James Kanze, Jan 2, 2008
    #6
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. kookey
    Replies:
    3
    Views:
    20,741
    Andrew Thompson
    Aug 20, 2005
  2. Patrick Hoffmann
    Replies:
    3
    Views:
    2,815
    Christian Janßen
    Aug 8, 2003
  3. Marcin Vorbrodt

    Global static variable vs static method

    Marcin Vorbrodt, Sep 5, 2003, in forum: C++
    Replies:
    3
    Views:
    5,405
    Denis Perelyubskiy
    Sep 5, 2003
  4. Roland Raschke
    Replies:
    1
    Views:
    1,076
    Kevin Goodsell
    Sep 22, 2003
  5. Jaco Naude
    Replies:
    1
    Views:
    410
    James Kanze
    Jul 25, 2008
Loading...

Share This Page