Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > template static member

Reply
Thread Tools

template static member

 
 
chgans
Guest
Posts: n/a
 
      09-27-2008
Hi all,

I'm having difficulties with some template static member, especially
when this member is a template instance, for example:
----
template<typename T>
class BaseT
{
public:
static void UseMap (const std::string &key, int value)
{
std::cout << gName << std::endl;
gMap[key] = value;
}

private:
static const std::string gName;
static std::map<std::string, int> gMap;
};

class DerivedT : public BaseT<DerivedT>
{
public:
// Some code soon or late....
};

// Now the specialization for BaseT<DerivedT>

// This one work fine
template<>
const std::string BaseT<DerivedT>::gName("Derived");

// This one gives me a linkage error:
// In function BaseT<DerivedT>::UseMap(...):
// undefined reference to BaseT<DerivedT>::gMap
template<>
std::map<std::string, int> BaseT<DerivedT>::gMap;

int main (int argc, char** argv)
{
DerivedT a;
a.UseMap ("test", 4);
}
----

So, i was wandering, if there is a special way to declare a static
member (which use the std::map template) of a template.

Later everything will be split up into several files, but for now i'm
using a single c++ source file to try to solve this problem. I've
tried with g++ 4.3.0 (x86_64, RH FC9) and a arm-linux-g++ 3.4, both
gives same results.

Thanks,
Christian
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      09-27-2008
chgans wrote:
> Hi all,
>
> I'm having difficulties with some template static member, especially
> when this member is a template instance, for example:
> ----
> template<typename T>
> class BaseT
> {
> public:
> static void UseMap (const std::string &key, int value)
> {
> std::cout << gName << std::endl;
> gMap[key] = value;
> }
>
> private:
> static const std::string gName;
> static std::map<std::string, int> gMap;
> };
>
> class DerivedT : public BaseT<DerivedT>
> {
> public:
> // Some code soon or late....
> };
>
> // Now the specialization for BaseT<DerivedT>
>
> // This one work fine
> template<>
> const std::string BaseT<DerivedT>::gName("Derived");
>
> // This one gives me a linkage error:
> // In function BaseT<DerivedT>::UseMap(...):
> // undefined reference to BaseT<DerivedT>::gMap
> template<>
> std::map<std::string, int> BaseT<DerivedT>::gMap;
>

Why try and specialise?

template <typename T>
std::map<std::string, int> BaseT<T>::gMap;

Will be fine.

--
Ian Collins.
 
Reply With Quote
 
 
 
 
SzymonWlodarski@gmail.com
Guest
Posts: n/a
 
      09-27-2008
On Sep 27, 3:49 pm, chgans <chg...@googlemail.com> wrote:
> Hi all,
>
> I'm having difficulties with some template static member, especially
> when this member is a template instance, for example:
> ----
> template<typename T>
> class BaseT
> {
> public:
> static void UseMap (const std::string &key, int value)
> {
> std::cout << gName << std::endl;
> gMap[key] = value;
> }
>
> private:
> static const std::string gName;
> static std::map<std::string, int> gMap;
>
> };
>
> class DerivedT : public BaseT<DerivedT>
> {
> public:
> // Some code soon or late....
>
> };
>
> // Now the specialization for BaseT<DerivedT>
>
> // This one work fine
> template<>
> const std::string BaseT<DerivedT>::gName("Derived");
>
> // This one gives me a linkage error:
> // In function BaseT<DerivedT>::UseMap(...):
> // undefined reference to BaseT<DerivedT>::gMap
> template<>
> std::map<std::string, int> BaseT<DerivedT>::gMap;
>
> int main (int argc, char** argv)
> {
> DerivedT a;
> a.UseMap ("test", 4);}
>
> ----
>
> So, i was wandering, if there is a special way to declare a static
> member (which use the std::map template) of a template.
>
> Later everything will be split up into several files, but for now i'm
> using a single c++ source file to try to solve this problem. I've
> tried with g++ 4.3.0 (x86_64, RH FC9) and a arm-linux-g++ 3.4, both
> gives same results.
>
> Thanks,
> Christian


It seems that if you specialize a static member you can't do it with a
default constructor. You can either write:

template< class T >
std::map<std::string, int> BaseT< T >::gMap;

or:

template<>
std::map<std::string, int> BaseT< DerivedT >::gMap( anotherMap );

However, I tested it using only one compiler (g++ 4.1.2) and I did not
look into the Standard so I am not sure that it is what it requires.

Example:

template< class T >
struct A
{
static void
push( T const & v )
{
vec.push_back( v );
}

static std::vector< T > vec;
};

template< class T >
std::vector< T > A< T >::vec;

/*
template<>
std::vector< double > A< double >::vec; // won't work
*/

template<>
std::vector< double > A< double >::vec( 10 ); // ok

int
main()
{
A< int >:ush( 10 );
A< double >:ush( 10.0 );
}

--
Szymon
 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      09-28-2008
On Sep 27, 10:45 pm, SzymonWlodar...@gmail.com wrote:
> On Sep 27, 3:49 pm, chgans <chg...@googlemail.com> wrote:


> > I'm having difficulties with some template static member,
> > especially when this member is a template instance, for
> > example:
> > ----
> > template<typename T>
> > class BaseT
> > {
> > public:
> > static void UseMap (const std::string &key, int value)
> > {
> > std::cout << gName << std::endl;
> > gMap[key] = value;
> > }


> > private:
> > static const std::string gName;
> > static std::map<std::string, int> gMap;
> > };


> > class DerivedT : public BaseT<DerivedT>
> > {
> > public:
> > // Some code soon or late....
> > };


> > // Now the specialization for BaseT<DerivedT>


> > // This one work fine
> > template<>
> > const std::string BaseT<DerivedT>::gName("Derived");


> > // This one gives me a linkage error:
> > // In function BaseT<DerivedT>::UseMap(...):
> > // undefined reference to BaseT<DerivedT>::gMap
> > template<>
> > std::map<std::string, int> BaseT<DerivedT>::gMap;


> > int main (int argc, char** argv)
> > {
> > DerivedT a;
> > a.UseMap ("test", 4);
> > }
> > ----


> > So, i was wandering, if there is a special way to declare a
> > static member (which use the std::map template) of a
> > template.


> It seems that if you specialize a static member you can't do
> it with a default constructor. You can either write:


> template< class T >
> std::map<std::string, int> BaseT< T >::gMap;


> or:


> template<>
> std::map<std::string, int> BaseT< DerivedT >::gMap( anotherMap );


> However, I tested it using only one compiler (g++ 4.1.2) and I
> did not look into the Standard so I am not sure that it is
> what it requires.


Note that a specialization is not a template, but rather a
declaration or definition of a non-template entity with a name
that looks like a template instantiation, to be used instead of
the instantiation.

Givan that, the basic problem in this is that without an
initializer, the compiler interprets the static member
specialization as a declaration, not a definition, and since
it's not a template, you need a definition (in one, and only
one, translation unit). See §14.7.3/15:

An explicit specialization of a static data member of a
template is a definition if the declaration includes an
initializer; otherwise, it is a declaration. [Note:
there is no syntax for the definition of a static data
member of a template which requires default
initialization.

template<> X Q<int>: ;

This is a declaration regardless of whether X can be
default initialized.]

Note the note!

Note too that formally, you can only provide a single
definition, which means that the definition should be in a
source file, and not in a header; i.e.:

In the header:
template< class T >
std::map< std::string, int > BaseT< DerivedT >::gMap ;

and then in one and only one source file (which includes the
header):
template< class T >
std::map< std::string, int > BaseT< DerivedT >::gMap(
std::map< std::string, int > BaseT< DerivedT >() ) ;
(Luckily, we can use the copy constructor in this case.)

--
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
 
Reply With Quote
 
chgans
Guest
Posts: n/a
 
      09-28-2008
On Sep 28, 8:23*am, James Kanze <james.ka...@gmail.com> wrote:
> On Sep 27, 10:45 pm, SzymonWlodar...@gmail.com wrote:
>
>
>
> > On Sep 27, 3:49 pm, chgans <chg...@googlemail.com> wrote:
> > > I'm having difficulties with some template static member,
> > > especially when this member is a template instance, for
> > > example:
> > > ----
> > > template<typename T>
> > > class BaseT
> > > {
> > > public:
> > > * static void UseMap (const std::string &key, int value)
> > > * {
> > > * * std::cout << gName << std::endl;
> > > * * gMap[key] = value;
> > > * }
> > > private:
> > > * static const std::string gName;
> > > * static std::map<std::string, int> gMap;
> > > };
> > > class DerivedT : public BaseT<DerivedT>
> > > {
> > > public:
> > > * *// Some code soon or late....
> > > };
> > > // Now the specialization for BaseT<DerivedT>
> > > // This one work fine
> > > template<>
> > > const std::string BaseT<DerivedT>::gName("Derived");
> > > // This one gives me a linkage error:
> > > // In function BaseT<DerivedT>::UseMap(...):
> > > // undefined reference to BaseT<DerivedT>::gMap
> > > template<>
> > > std::map<std::string, int> BaseT<DerivedT>::gMap;
> > > int main (int argc, char** argv)
> > > {
> > > * DerivedT a;
> > > * a.UseMap ("test", 4);
> > > }
> > > ----
> > > So, i was wandering, if there is a special way to declare a
> > > static member (which use the std::map template) of a
> > > template.

> > It seems that if you specialize a static member you can't do
> > it with a default constructor. You can either write:
> > template< class T >
> > std::map<std::string, int> BaseT< T >::gMap;
> > or:
> > template<>
> > std::map<std::string, int> BaseT< DerivedT >::gMap( anotherMap );
> > However, I tested it using only one compiler (g++ 4.1.2) and I
> > did not look into the Standard so I am not sure that it is
> > what it requires.

>
> Note that a specialization is not a template, but rather a
> declaration or definition of a non-template entity with a name
> that looks like a template instantiation, to be used instead of
> the instantiation.
>
> Givan that, the basic problem in this is that without an
> initializer, the compiler interprets the static member
> specialization as a declaration, not a definition, and since
> it's not a template, you need a definition (in one, and only
> one, translation unit). *See §14.7.3/15:
>
> * * An explicit specialization of a static data member of a
> * * template is a definition if the declaration includes an
> * * initializer; otherwise, it is a declaration. [Note:
> * * there is no syntax for the definition of a static data
> * * member of a template which requires default
> * * initialization.
>
> * * * * template<> X Q<int>: ;
>
> * * This is a declaration regardless of whether X can be
> * * default initialized.]
>
> Note the note!
>
> Note too that formally, you can only provide a single
> definition, which means that the definition should be in a
> source file, and not in a header; i.e.:
>
> In the header:
> * * template< class T >
> * * std::map< std::string, int > BaseT< DerivedT >::gMap ;
>
> and then in one and only one source file (which includes the
> header):
> * * template< class T >
> * * std::map< std::string, int > BaseT< DerivedT >::gMap(
> * * * * * * std::map< std::string, int > BaseT< DerivedT >() ) ;
> (Luckily, we can use the copy constructor in this case.)


Thank you all,
Problem solved now!


>
> --
> James Kanze (GABI Software) * * * * * * email:james.ka...@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


 
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
overloading non-template member functions with template member functions Hicham Mouline C++ 1 04-24-2009 07:47 AM
overloading non-template member functions with template member functions Hicham Mouline C++ 0 04-23-2009 11:42 AM
Can a static member function access non-static member? dolphin C++ 3 12-05-2007 12:39 PM
template class static template type member address allocation Frederiek C++ 1 09-14-2006 03:10 PM
parse error in gcc but success in vc.net, call a non_template class's template member function from a template class's member function! ken C++ 2 06-28-2005 06:57 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57