* 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).