public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* 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).