* I can not compile code from <<modern c++ design>>
@ 2003-04-07 9:24 Di Yang
2003-04-07 10:59 ` Matthias Oltmanns
0 siblings, 1 reply; 8+ messages in thread
From: Di Yang @ 2003-04-07 9:24 UTC (permalink / raw)
To: gcc-help
Hi,
Following code is listed in chapter 2.7 Detecting Convertibility and
Inheritance at Compile Time:
#include <iostream>
template <class T, class U>
class Conversion
{
typedef char Small;
class Big { char dummy[2]; };
static Small Test(U);
static Big Test(...);
static T MakeT();
public:
enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
};
int main()
{
using namespace std;
cout<< Conversion<double, int>::exists << ' '<< Conversion<char,
char*>::exists;
return 0;
}
and I got following errors:
C:\ttt>gcc -o template template.cpp
template.cpp:5: warning: all member functions in class `Conversion<T, U>' are
private
template.cpp: In instantiation of `Conversion<double, int>':
template.cpp:21: instantiated from here
template.cpp:21: invalid use of undefined type `class Conversion<double, int>'
template.cpp:5: declaration of `class Conversion<double, int>'
template.cpp:21: invalid use of undefined type `class Conversion<double, int>'
template.cpp:5: declaration of `class Conversion<double, int>'
template.cpp:21: enumerator value for `exists' not integer constant
template.cpp: In instantiation of `Conversion<char, char*>':
template.cpp:21: instantiated from here
template.cpp:21: invalid use of undefined type `class Conversion<char, char*>'
template.cpp:5: declaration of `class Conversion<char, char*>'
template.cpp:21: invalid use of undefined type `class Conversion<char, char*>'
template.cpp:5: declaration of `class Conversion<char, char*>'
template.cpp:21: enumerator value for `exists' not integer constant
Anyone can help me?
Thanks!
Di Yang
Best Regards
Di Yang
Phone: 86-10-85296529 ext.130 QUALCOMM CDMA Technologies
Fax: 86-10-85296110 Floor 26th, North Tower, Kerry Center
Mobile: 86-13301338054 No. 1, Guang Hua Road, Chao Yang
District
Email: diy@qualcomm.com Beijing 100020, China
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-07 9:24 I can not compile code from <<modern c++ design>> Di Yang
@ 2003-04-07 10:59 ` Matthias Oltmanns
2003-04-07 13:54 ` Di Yang
2003-04-07 19:49 ` Oscar Fuentes
0 siblings, 2 replies; 8+ messages in thread
From: Matthias Oltmanns @ 2003-04-07 10:59 UTC (permalink / raw)
To: Di Yang; +Cc: gcc-help
Am Mon, 2003-04-07 um 11.24 schrieb Di Yang:
> Hi,
>
> public:
> enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
Hi,
this seems to be not valid C++ code because the calls to the
static members 'Test' and 'MakeT' are not const expressions at compile
time.
For assignments to enum literals there are only integer expressions
allowed which are evaluated at compile time.
cu
Matthias
--
Matthias Oltmanns
Tel: 04421-1543-274
mail: Mathias.Oltmanns.Oltmanns@sysde.eads.net
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-07 10:59 ` Matthias Oltmanns
@ 2003-04-07 13:54 ` Di Yang
2003-04-07 14:42 ` Matthias Oltmanns
2003-04-07 19:49 ` Oscar Fuentes
1 sibling, 1 reply; 8+ messages in thread
From: Di Yang @ 2003-04-07 13:54 UTC (permalink / raw)
To: Matthias Oltmanns; +Cc: gcc-help
At 13:02 4/7/2003 +0200, Matthias Oltmanns wrote:
>Am Mon, 2003-04-07 um 11.24 schrieb Di Yang:
> > Hi,
> >
> > public:
> > enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
>
>Hi,
>
>this seems to be not valid C++ code because the calls to the
>static members 'Test' and 'MakeT' are not const expressions at compile
>time.
>For assignments to enum literals there are only integer expressions
>allowed which are evaluated at compile time.
>
>cu
>Matthias
Thank you, I changed the code as following and passed GCC 3.2: -Di
template <class T, class U>
struct ConversionHelper
{
typedef char Small;
struct Big { char dummy[2]; };
static Big Test(...);
static Small Test(U);
static T MakeT();
};
template <class T, class U>
struct Conversion
{
typedef ConversionHelper<T, U> H;
enum { exists = sizeof(typename H::Small) ==
sizeof(H::Test(H::MakeT())) };
};
......
C:\ttt>g++ -o template template.cpp
template.cpp: In instantiation of `Conversion<double, int>':
template.cpp:40: instantiated from here
template.cpp:40: warning: passing `double' for argument 1 of `static char
ConversionHelper<T, U>::Test(U) [with T = double, U = int]'
C:\ttt>template
1 0
C:\ttt>
>--
>Matthias Oltmanns
>
>Tel: 04421-1543-274
>mail: Mathias.Oltmanns.Oltmanns@sysde.eads.net
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-07 13:54 ` Di Yang
@ 2003-04-07 14:42 ` Matthias Oltmanns
2003-04-08 9:13 ` Di Yang
0 siblings, 1 reply; 8+ messages in thread
From: Matthias Oltmanns @ 2003-04-07 14:42 UTC (permalink / raw)
To: Di Yang; +Cc: gcc-help
Am Mon, 2003-04-07 um 15.54 schrieb Di Yang:
> At 13:02 4/7/2003 +0200, Matthias Oltmanns wrote:
> >Am Mon, 2003-04-07 um 11.24 schrieb Di Yang:
> > > Hi,
> > >
> > > public:
> > > enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
> >
> >Hi,
> >
> >this seems to be not valid C++ code because the calls to the
> >static members 'Test' and 'MakeT' are not const expressions at compile
> >time.
> >For assignments to enum literals there are only integer expressions
> >allowed which are evaluated at compile time.
> >
> >cu
> >Matthias
>
> Thank you, I changed the code as following and passed GCC 3.2: -Di
>
> template <class T, class U>
> struct ConversionHelper
> {
> typedef char Small;
> struct Big { char dummy[2]; };
> static Big Test(...);
> static Small Test(U);
> static T MakeT();
> };
>
> template <class T, class U>
> struct Conversion
> {
> typedef ConversionHelper<T, U> H;
> enum { exists = sizeof(typename H::Small) ==
> sizeof(H::Test(H::MakeT())) };
>
> };
> ......
>
>
> C:\ttt>g++ -o template template.cpp
> template.cpp: In instantiation of `Conversion<double, int>':
> template.cpp:40: instantiated from here
> template.cpp:40: warning: passing `double' for argument 1 of `static char
> ConversionHelper<T, U>::Test(U) [with T = double, U = int]'
>
> C:\ttt>template
> 1 0
> C:\ttt>
Hi,
i'am confused. Your changes shows that I'm wrong. But i' cant see why.
You could also change your first version making all members public:
class Conversion
{
public:
typedef char Small;
class Big { char dummy[2]; };
static Small Test(U);
static Big Test(...);
static T MakeT();
enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
};
which also works.
So, if the initialization of the enum is legal it should be legal in
your previous version having only the enum public.
cu
Matthias
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-07 10:59 ` Matthias Oltmanns
2003-04-07 13:54 ` Di Yang
@ 2003-04-07 19:49 ` Oscar Fuentes
1 sibling, 0 replies; 8+ messages in thread
From: Oscar Fuentes @ 2003-04-07 19:49 UTC (permalink / raw)
To: gcc-help
Matthias Oltmanns <Mathias.Oltmanns.Oltmanns@sysde.eads.net> writes:
> Am Mon, 2003-04-07 um 11.24 schrieb Di Yang:
>> Hi,
>>
>> public:
>> enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
>
> Hi,
>
> this seems to be not valid C++ code because the calls to the
> static members 'Test' and 'MakeT' are not const expressions at compile
> time.
It is valid C++. Note that we are applying 'sizeof' to the result
*type* of the function.
> For assignments to enum literals there are only integer expressions
> allowed which are evaluated at compile time.
Right. And 'sizeof' is always a compile-time thing.
To the OP: There is a GCC compatible implementation of Loki on
www.moderncppdesign.com
--
Oscar
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-07 14:42 ` Matthias Oltmanns
@ 2003-04-08 9:13 ` Di Yang
2003-04-08 9:57 ` Matthias Oltmanns
0 siblings, 1 reply; 8+ messages in thread
From: Di Yang @ 2003-04-08 9:13 UTC (permalink / raw)
To: Matthias Oltmanns; +Cc: gcc-help
>Hi,
>
>i'am confused. Your changes shows that I'm wrong. But i' cant see why.
>You could also change your first version making all members public:
>
>class Conversion
>{
>public:
> typedef char Small;
> class Big { char dummy[2]; };
>
> static Small Test(U);
> static Big Test(...);
> static T MakeT();
>
> enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
>};
>
>which also works.
Sorry, but I still failed at this point:
#include <iostream>
template <class T, class U>
class Conversion
{
public:
typedef char Small;
class Big { char dummy[2]; };
static Small Test(U);
static Big Test(...);
static T MakeT();
enum { exists = sizeof(Test(MakeT())) == sizeof(Small) };
};
int main()
{
using namespace std;
cout<< Conversion<double, int>::exists << ' '<< Conversion<char,
char*>::exists;
return 0;
}
Same errror as before:
C:\ttt>g++ -o template template.cpp
template.cpp: In instantiation of `Conversion<double, int>':
template.cpp:42: instantiated from here
template.cpp:42: invalid use of undefined type `class Conversion<double, int>'
template.cpp:5: declaration of `class Conversion<double, int>'
template.cpp:42: invalid use of undefined type `class Conversion<double, int>'
template.cpp:5: declaration of `class Conversion<double, int>'
template.cpp:42: enumerator value for `exists' not integer constant
template.cpp: In instantiation of `Conversion<char, char*>':
template.cpp:42: instantiated from here
template.cpp:42: invalid use of undefined type `class Conversion<char, char*>'
template.cpp:5: declaration of `class Conversion<char, char*>'
template.cpp:42: invalid use of undefined type `class Conversion<char, char*>'
template.cpp:5: declaration of `class Conversion<char, char*>'
template.cpp:42: enumerator value for `exists' not integer constant
C:\ttt>g++ -dumpversion
3.2
C:\ttt>
Only with the Conversionhelper version works for me.
Thanks.
Di
>So, if the initialization of the enum is legal it should be legal in
>your previous version having only the enum public.
>
>cu
>Matthias
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-08 9:13 ` Di Yang
@ 2003-04-08 9:57 ` Matthias Oltmanns
2003-04-09 0:44 ` Di Yang
0 siblings, 1 reply; 8+ messages in thread
From: Matthias Oltmanns @ 2003-04-08 9:57 UTC (permalink / raw)
To: Di Yang; +Cc: gcc-help, gcc
Am Die, 2003-04-08 um 10.48 schrieb Di Yang:
>
> Sorry, but I still failed at this point:
>
Hmmm ... me too :-) I've tested yesterday the wrong file.
I've learned, that using sizeof with a function as parameter is a
constant integer expression and therefore valid in using
enumeration initializers.
The question remaining is, why does the following not compile:
#include <iostream>
template<typename T>
class Foo
{
public:
static T bar();
enum { test = sizeof(bar()) };
};
int main()
{
std::cout << Foo<char>::test << std::endl;
}
> g++ -o conv conv.cc
conv.cc: In instantiation of `Foo<char>':
conv.cc:14: instantiated from here
conv.cc:14: invalid use of undefined type `class Foo<char>'
conv.cc:5: declaration of `class Foo<char>'
conv.cc:14: enumerator value for `test' not integer constant
> g++ --version
g++ (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is
NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
Is it a bug or does i still miss some point.
cu
Matthias
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: I can not compile code from <<modern c++ design>>
2003-04-08 9:57 ` Matthias Oltmanns
@ 2003-04-09 0:44 ` Di Yang
0 siblings, 0 replies; 8+ messages in thread
From: Di Yang @ 2003-04-09 0:44 UTC (permalink / raw)
To: Matthias Oltmanns; +Cc: gcc-help, gcc
At 12:00 4/8/2003 +0200, Matthias Oltmanns wrote:
>Am Die, 2003-04-08 um 10.48 schrieb Di Yang:
> >
> > Sorry, but I still failed at this point:
> >
>
>Hmmm ... me too :-) I've tested yesterday the wrong file.
>
>I've learned, that using sizeof with a function as parameter is a
>constant integer expression and therefore valid in using
>enumeration initializers.
>
>The question remaining is, why does the following not compile:
>
>#include <iostream>
>
>template<typename T>
>class Foo
>{
>public:
> static T bar();
>
> enum { test = sizeof(bar()) };
>};
>
>int main()
>{
> std::cout << Foo<char>::test << std::endl;
>}
>
> > g++ -o conv conv.cc
>conv.cc: In instantiation of `Foo<char>':
>conv.cc:14: instantiated from here
>conv.cc:14: invalid use of undefined type `class Foo<char>'
>conv.cc:5: declaration of `class Foo<char>'
>conv.cc:14: enumerator value for `test' not integer constant
>
> > g++ --version
>g++ (GCC) 3.2 20020903 (Red Hat Linux 8.0 3.2-7)
>Copyright (C) 2002 Free Software Foundation, Inc.
>This is free software; see the source for copying conditions. There is
>NO
>warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
>PURPOSE.
>
>Is it a bug or does i still miss some point.
I don't know either, can someone familiar c++ standard explain this?
And with a FooHelper, it works:
// code start
#include <iostream>
template <typename T>
class FooHelper
{
public:
static T bar();
};
template<typename T>
class Foo
{
public:
enum { test = sizeof(FooHelper<T>::bar()) };
};
int main()
{
std::cout << Foo<char>::test << std::endl;
}
// code end
Thanks.
Di
>cu
>Matthias
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2003-04-09 0:44 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-04-07 9:24 I can not compile code from <<modern c++ design>> Di Yang
2003-04-07 10:59 ` Matthias Oltmanns
2003-04-07 13:54 ` Di Yang
2003-04-07 14:42 ` Matthias Oltmanns
2003-04-08 9:13 ` Di Yang
2003-04-08 9:57 ` Matthias Oltmanns
2003-04-09 0:44 ` Di Yang
2003-04-07 19:49 ` Oscar Fuentes
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).