public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* Linker error with static data member in templated class
@ 2010-10-01 10:43 Andy Gibbs
  2010-10-01 15:43 ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Andy Gibbs @ 2010-10-01 10:43 UTC (permalink / raw)
  To: gcc-help

Hi,

I am using gcc 4.4.5 with the c++0x extensions turned on and am having some 
issues defining static variables inside partially specialised template 
classes.  I've put together some fairly straight-forward demonstration code 
as follows:

struct C1
 {
 C1() : i(0)
  { printf("default constructor\n"); }

 C1(const C1& other) = delete;

/*C1(const C1& other) : i(other.i)
  { printf("copy constructor\n"); }*/

 int i;
 };

struct C2
 {
 static C1 op;
 };

template <typename T>
struct C3
 {
 static C1 op;
 };

template <typename T>
struct C4
 {
 static C1 op;
 };

// Initialise C2::op
C1 C2::op;

// Initialise C3::op for type int
template<> C1 C3<int>::op;

// Initialise C4::op for type int
template<> C1 C4<int>::op = C1();


int main()
 {
 printf("%i\n", C2::op.i);
 printf("%i\n", C3<int>::op.i);
 printf("%i\n", C4<int>::op.i);
 return 0;
 }


Like this the code fails to compile with the error "deleted function 
C1::C1(const C1&) used here" referring to the line that initialises 
C4<int>::op since it appears to need the copy constructor.  I say "appears" 
since if I give C1 a copy constructor, then I find when running the code 
that it doesn't actually call the copy constructor.

However, if the compiler error is fixed, then a separate linker error 
occurs: "undefined reference to 'C3<int>::op'".  It therefore seems that it 
is not possible, at least by this syntax, to default construct C3<int>::op. 
This is in contrast to the default construction of C2::op which is possible.

Is there another syntax by which I can default construct C3<int>::op? - 
since the implementation I will need of C1 requires that the copy 
constructor be disabled and so the syntax I use with C4<int>::op is not 
going to be possible.

Thanks!

Andy

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linker error with static data member in templated class
  2010-10-01 10:43 Linker error with static data member in templated class Andy Gibbs
@ 2010-10-01 15:43 ` Ian Lance Taylor
  2010-10-04  8:22   ` Andy Gibbs
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2010-10-01 15:43 UTC (permalink / raw)
  To: Andy Gibbs; +Cc: gcc-help

Andy Gibbs <andyg1001@hotmail.co.uk> writes:

> // Initialise C3::op for type int
> template<> C1 C3<int>::op;

You are using specialization syntax but it seems to me that you want
instantiation syntax, which would be

template C1 C3<int>::op;

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linker error with static data member in templated class
  2010-10-01 15:43 ` Ian Lance Taylor
@ 2010-10-04  8:22   ` Andy Gibbs
  2010-10-04 10:32     ` Andy Gibbs
  0 siblings, 1 reply; 6+ messages in thread
From: Andy Gibbs @ 2010-10-04  8:22 UTC (permalink / raw)
  To: Ian Lance Taylor, gcc-help

On Friday, October 01, 2010 5:43 PM, Ian Lance Taylor wrote:

> Andy Gibbs <andyg1001@hotmail.co.uk> writes:
>
>> // Initialise C3::op for type int
>> template<> C1 C3<int>::op;
>
> You are using specialization syntax but it seems to me that you want
> instantiation syntax, which would be
>
> template C1 C3<int>::op;
>

Thank you.  It didn't quite work since this on its own gave a "explicit 
instantiation of 'C3<int>::op' but no definition available" error.  However, 
doing:

template <typename T> C1 C3<T>::op;
template C1 C3<int>::op;

compiled and linked fine.

Thanks for pointing me in the right direction!

Andy


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linker error with static data member in templated class
  2010-10-04  8:22   ` Andy Gibbs
@ 2010-10-04 10:32     ` Andy Gibbs
  2010-10-04 20:28       ` Ian Lance Taylor
  0 siblings, 1 reply; 6+ messages in thread
From: Andy Gibbs @ 2010-10-04 10:32 UTC (permalink / raw)
  To: gcc-help

Hi again,

Sorry, I think my previous demonstrator code was too simple for the target 
application in hand.  I hoped the lesson learned would translate, but in 
this case it didn't.

The following code is *much* closer to the actual code, but hopefully still 
stripping out the main complexity of it.  The actual problem I'm having 
comes where the static data member has a type that is a template class that 
takes a pointer to another member data type.  It really seems this specific, 
I'm afraid.  The "revised" demonstrator code is as follows:

template <char* T>
struct C1
  {
  C1() { }
/*C1(const C1& other) = delete;*/

  char operator()()
    { return *T; }
  };

struct C2
  {
  static char m;
  static C1<&m> op;
  };

template <typename T>
struct C3
  {
  static char m;
  static C1<&m> op1;
  static C1<&C2::m> op2;
  };

// Initialise C2::m and C2::op
char C2::m = 'a';
C1<&C2::m> C2::op;

// Initialise C3::m for type int
template<> char C3<int>::m = 'b';

// Initialise C3::op2 for type int
template <typename T> C1<&C2::m> C3<T>::op2;
template C1<&C2::m> C3<int>::op2;

// Initialise C2::op1 for type int
#if 0
/** This doesn't work **/
template <typename T> C1<&C3<T>::m> C3<T>::op1;
template C1<&C3<int>::m> C3<int>::op1;
#elif 0
/** This doesn't work either **/
template<>
C1<&C3<int>::m> C3<int>::op1;
#else
/** This requires the copy-constructor - bad! **/
template<>
C1<&C3<int>::m> C3<int>::op1 = C1<&C3<int>::m>();
#endif

int main()
  {
  printf("%c\n", C2::op());
  printf("%c\n", C3<int>::op1());
  printf("%c\n", C3<int>::op2());
  return 0;
  }


The code as presented will compile and run, but as before, I wish to disable 
the copy constructor in C1.  The two alternative syntaxes that I tried are 
in the code disabled with #if 0.  I expect that I'm missing a 'typename' or 
a 'template' keyword somewhere, but I cannot find where.

Thank you again for any help you can give me!

Andy



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linker error with static data member in templated class
  2010-10-04 10:32     ` Andy Gibbs
@ 2010-10-04 20:28       ` Ian Lance Taylor
  2010-10-05  7:00         ` Andy Gibbs
  0 siblings, 1 reply; 6+ messages in thread
From: Ian Lance Taylor @ 2010-10-04 20:28 UTC (permalink / raw)
  To: Andy Gibbs; +Cc: gcc-help

Andy Gibbs <andyg1001@hotmail.co.uk> writes:

> #if 0
> /** This doesn't work **/
> template <typename T> C1<&C3<T>::m> C3<T>::op1;
> template C1<&C3<int>::m> C3<int>::op1;

This case works fine in mainline gcc, and it looks right to me.  It may
simply be a bug in the version of the compiler you are using.

Ian

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: Linker error with static data member in templated class
  2010-10-04 20:28       ` Ian Lance Taylor
@ 2010-10-05  7:00         ` Andy Gibbs
  0 siblings, 0 replies; 6+ messages in thread
From: Andy Gibbs @ 2010-10-05  7:00 UTC (permalink / raw)
  To: Ian Lance Taylor, gcc-help

On Monday, October 04, 2010 10:27 PM, Ian Lance Taylor wrote:

>> #if 0
>> /** This doesn't work **/
>> template <typename T> C1<&C3<T>::m> C3<T>::op1;
>> template C1<&C3<int>::m> C3<int>::op1;
>
> This case works fine in mainline gcc, and it looks right to me.  It may
> simply be a bug in the version of the compiler you are using.
>
> Ian
>

That is good to know.  In that case I'll migrate up to 4.5.1 and see if that 
solves the problem.

Thank you for all your help.

Andy


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-10-05  7:00 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-10-01 10:43 Linker error with static data member in templated class Andy Gibbs
2010-10-01 15:43 ` Ian Lance Taylor
2010-10-04  8:22   ` Andy Gibbs
2010-10-04 10:32     ` Andy Gibbs
2010-10-04 20:28       ` Ian Lance Taylor
2010-10-05  7:00         ` Andy Gibbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).