Re: Template specialization and static data member

Discussion in 'C++' started by Johan Nilsson, Jun 24, 2003.

  1. "Victor Bazarov" <> wrote in message
    news:...
    > "Johan Nilsson" <> wrote...
    > > ---------------------------------------
    > > The error I get is the following:
    > >
    > > $ cxx x.cpp
    > >
    > > foo<1>::bars[] =
    > > ........^
    > > %CXX-E-NOCREINCOBJ, Cannot create member "foo<id>::bars [with id=1]" of
    > > incomplete type "const foo<1>::bar []".
    > > at line number 5 in file DISK$USER1:[POSNET]X.CPP;6
    > >
    > >
    > > ----------------------
    > >
    > > Am I wrong, or is it the compiler? Workaround available?

    >
    >
    > Try giving it a size:
    >
    > ... foo<1>::bars[3] =
    >
    > Victor
    >


    Doesn't help. I've been doing some further investigation and it seems like
    the compiler requires me to write an explicit specialization for the entire
    class when the data type of the static data member isn't a built-in.

    Is the compiler right (as said, g++ and VC.NET allows it)?

    // Johan
    Johan Nilsson, Jun 24, 2003
    #1
    1. Advertising

  2. "Johan Nilsson" <> wrote...
    > "Victor Bazarov" <> wrote in message
    > news:...
    > > "Johan Nilsson" <> wrote...
    > > > ---------------------------------------
    > > > The error I get is the following:
    > > >
    > > > $ cxx x.cpp
    > > >
    > > > foo<1>::bars[] =
    > > > ........^
    > > > %CXX-E-NOCREINCOBJ, Cannot create member "foo<id>::bars [with id=1]"

    of
    > > > incomplete type "const foo<1>::bar []".
    > > > at line number 5 in file DISK$USER1:[POSNET]X.CPP;6
    > > >
    > > >
    > > > ----------------------
    > > >
    > > > Am I wrong, or is it the compiler? Workaround available?

    > >
    > >
    > > Try giving it a size:
    > >
    > > ... foo<1>::bars[3] =
    > >
    > > Victor
    > >

    >
    > Doesn't help. I've been doing some further investigation and it seems like
    > the compiler requires me to write an explicit specialization for the

    entire
    > class when the data type of the static data member isn't a built-in.
    >
    > Is the compiler right (as said, g++ and VC.NET allows it)?


    I probably missed the part that you were specialising it, and I
    apologise. Yes, if you need a specialisation of a member, you
    will have to first specialise the entire class. Language does
    require that.

    Victor
    Victor Bazarov, Jun 24, 2003
    #2
    1. Advertising

  3. "Victor Bazarov" <> wrote in message
    news:...
    > "Johan Nilsson" <> wrote...
    > > "Victor Bazarov" <> wrote in message
    > > news:...
    > > > "Johan Nilsson" <> wrote...
    > > > > ---------------------------------------
    > > > > The error I get is the following:
    > > > >


    [snip]

    > >
    > > Is the compiler right (as said, g++ and VC.NET allows it)?

    >
    > I probably missed the part that you were specialising it, and I
    > apologise. Yes, if you need a specialisation of a member, you
    > will have to first specialise the entire class. Language does
    > require that.
    >


    Thanks for your reply (and sorry if reiterating). I'd just like to ask if
    you're really sure if this true for a _static_ data member, I've tried to
    read up on it in the standard - and it's not really clear to me what it says
    there (it states that static data members can be explicitly specialized, but
    no examples included).

    The thing that makes me wonder is that I can do this using g++ 3.0x, g++ 3.2
    and VC.NET 7.x. It also works with the very same compiler that caused me to
    send the originating post of this thread (DEC C++ 6.5 for OpenVMS), as long
    as I use a built-in data type, IIRC (out of my head only):

    ------------------ example.cpp -----------
    #include <iostream>

    template<int id>
    struct foo
    {
    static const double d;
    };

    template<>
    const double
    foo<1>::d = 0.1;

    template<>
    const double
    foo<2>::d = 0.2;

    int main(int, char*[])
    {
    std::cout << foo<1>::d << std::endl; // prints "0.1"
    std::cout << foo<2>::d << std::endl; // prints "0.2"
    std::cout << foo<0>::d << std::endl; // fails a link-time
    return 0;
    }

    --------------------------------------------

    Regards // Johan
    Johan Nilsson, Jun 24, 2003
    #3
  4. "Johan Nilsson" <> wrote...
    >
    > "Victor Bazarov" <> wrote in message
    > news:...
    > > "Johan Nilsson" <> wrote...
    > > > "Victor Bazarov" <> wrote in message
    > > > news:...
    > > > > "Johan Nilsson" <> wrote...
    > > > > > ---------------------------------------
    > > > > > The error I get is the following:
    > > > > >

    >
    > [snip]
    >
    > > >
    > > > Is the compiler right (as said, g++ and VC.NET allows it)?

    > >
    > > I probably missed the part that you were specialising it, and I
    > > apologise. Yes, if you need a specialisation of a member, you
    > > will have to first specialise the entire class. Language does
    > > require that.
    > >

    >
    > Thanks for your reply (and sorry if reiterating). I'd just like to ask if
    > you're really sure if this true for a _static_ data member, I've tried to
    > read up on it in the standard - and it's not really clear to me what it

    says
    > there (it states that static data members can be explicitly specialized,

    but
    > no examples included).
    >
    > The thing that makes me wonder is that I can do this using g++ 3.0x, g++

    3.2
    > and VC.NET 7.x. It also works with the very same compiler that caused me

    to
    > send the originating post of this thread (DEC C++ 6.5 for OpenVMS), as

    long
    > as I use a built-in data type, IIRC (out of my head only):
    >
    > ------------------ example.cpp -----------
    > #include <iostream>
    >
    > template<int id>
    > struct foo
    > {
    > static const double d;
    > };
    >
    > template<>
    > const double
    > foo<1>::d = 0.1;
    >
    > template<>
    > const double
    > foo<2>::d = 0.2;
    >
    > int main(int, char*[])
    > {
    > std::cout << foo<1>::d << std::endl; // prints "0.1"
    > std::cout << foo<2>::d << std::endl; // prints "0.2"
    > std::cout << foo<0>::d << std::endl; // fails a link-time
    > return 0;
    > }
    >
    > --------------------------------------------


    Alright, I should pay attention this time...

    Full specialisations of member functions or static data members
    of a class template can be made without specialising the entire
    class. That's what you're seeing here.

    Partial specialisation of a member function or static data member
    requires the existence of its enclosing partial specialisation of
    the class template.

    The original error you were getting was due to the fact that you
    had a _definition_ of an explicit specialisation of a static data
    member of an incomplete type. That prompted me to suggest the
    use of the size.

    -------------------------------------------- this code
    template<int i> struct A
    {
    struct B { int j; };
    static B b[];
    };

    template<> A<1>::B A<1>::b[];

    int main()
    {
    A<1>::b[0].j = 42;
    }
    --------------------------------------------------------
    contains the declaration of the explicit specialisation of a static
    data member and makes the use of it. It should and does compile OK.

    Perhaps the problem you've been having with the declarations of
    static data members explicit specialisations are due to compiler
    non-compliance?

    Victor
    Victor Bazarov, Jun 24, 2003
    #4
  5. "Victor Bazarov" <> wrote in message
    news:...
    > "Johan Nilsson" <> wrote...
    > >


    [snip]

    > >
    > > --------------------------------------------

    >
    > Alright, I should pay attention this time...
    >
    > Full specialisations of member functions or static data members
    > of a class template can be made without specialising the entire
    > class. That's what you're seeing here.


    Yes, that was what I believed as well. Interpreting the standard though,
    requires a bit more practice for me.

    >
    > Partial specialisation of a member function or static data member
    > requires the existence of its enclosing partial specialisation of
    > the class template.
    >
    > The original error you were getting was due to the fact that you
    > had a _definition_ of an explicit specialisation of a static data
    > member of an incomplete type. That prompted me to suggest the
    > use of the size.


    No, I originally had the declaration (in the header file) _and_ a definition
    (in the source file).

    >
    > -------------------------------------------- this code
    > template<int i> struct A
    > {
    > struct B { int j; };
    > static B b[];
    > };
    >
    > template<> A<1>::B A<1>::b[];
    >
    > int main()
    > {
    > A<1>::b[0].j = 42;
    > }
    > --------------------------------------------------------
    > contains the declaration of the explicit specialisation of a static
    > data member and makes the use of it. It should and does compile OK.


    Compiles ok, does not link (typo?) - or are you having the definition
    elsewhere?

    >
    > Perhaps the problem you've been having with the declarations of
    > static data members explicit specialisations are due to compiler
    > non-compliance?


    Probably, that's what I believed. I just wanted to get some second opinions.

    Thanks // Johan
    Johan Nilsson, Jun 25, 2003
    #5
  6. "Johan Nilsson" <> wrote...
    >
    > "Victor Bazarov" <> wrote in message
    > news:...

    [...]
    > > -------------------------------------------- this code
    > > template<int i> struct A
    > > {
    > > struct B { int j; };
    > > static B b[];
    > > };
    > >
    > > template<> A<1>::B A<1>::b[];
    > >
    > > int main()
    > > {
    > > A<1>::b[0].j = 42;
    > > }
    > > --------------------------------------------------------
    > > contains the declaration of the explicit specialisation of a static
    > > data member and makes the use of it. It should and does compile OK.

    >
    > Compiles ok, does not link (typo?) - or are you having the definition
    > elsewhere?


    I didn't try to link it. And it should link OK if the definition
    exists in the program (in a different translation unit).

    V
    Victor Bazarov, Jun 25, 2003
    #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. Dave
    Replies:
    4
    Views:
    7,664
    pdixtl
    Jun 4, 2010
  2. Ruben Campos
    Replies:
    3
    Views:
    6,463
  3. BigMan
    Replies:
    1
    Views:
    524
  4. Joseph Turian
    Replies:
    4
    Views:
    583
    John Carson
    Mar 20, 2006
  5. mike b
    Replies:
    14
    Views:
    3,261
    Greg Herlihy
    Oct 17, 2007
Loading...

Share This Page