Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c++ > #10109 > unrolled thread

static constants in a class

Started byUrs Thuermann <urs@isnogud.escape.de>
First post2011-09-14 23:43 +0200
Last post2011-09-15 02:50 -0700
Articles 19 — 8 participants

Back to article view | Back to comp.lang.c++


Contents

  static constants in a class Urs Thuermann <urs@isnogud.escape.de> - 2011-09-14 23:43 +0200
    Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-15 10:21 +1200
    Re: static constants in a class Leigh Johnston <leigh@i42.co.uk> - 2011-09-15 00:06 +0100
      Re: static constants in a class Leigh Johnston <leigh@i42.co.uk> - 2011-09-15 00:16 +0100
    Re: static constants in a class Juha Nieminen <nospam@thanks.invalid> - 2011-09-15 06:46 +0000
    Re: static constants in a class Marc <marc.glisse@gmail.com> - 2011-09-15 07:59 +0000
      Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-15 20:09 +1200
        Re: static constants in a class Marc <marc.glisse@gmail.com> - 2011-09-15 08:11 +0000
          Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-15 21:20 +1200
            Re: static constants in a class Marc <marc.glisse@gmail.com> - 2011-09-15 14:03 +0000
              Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-16 09:32 +1200
                Re: static constants in a class Marc <marc.glisse@gmail.com> - 2011-09-16 04:28 +0000
    Re: static constants in a class Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-09-15 10:50 +0200
      Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-15 21:17 +1200
        Re: static constants in a class Alain Ketterlin <alain@dpt-info.u-strasbg.fr> - 2011-09-15 11:48 +0200
        Re: static constants in a class Christopher <cpisz@austin.rr.com> - 2011-09-15 14:24 -0700
          Re: static constants in a class Ian Collins <ian-news@hotmail.com> - 2011-09-16 09:32 +1200
            Re: static constants in a class Leigh Johnston <leigh@i42.co.uk> - 2011-09-15 22:54 +0100
    Re: static constants in a class TonyO <guinness.tony@gmail.com> - 2011-09-15 02:50 -0700

#10109 — static constants in a class

FromUrs Thuermann <urs@isnogud.escape.de>
Date2011-09-14 23:43 +0200
Subjectstatic constants in a class
Message-ID<ygfboumyf3c.fsf@janus.isnogud.escape.de>
How should one define a constant, say of type int, in a class?  The
only way that worked for me in all cases is to delcare the constant in
the class in the header file and define its value in the
implementation file:

---- foo.hh ----
    class Foo {
    public:
    	static const int N;
    	...
    };
---- foo.cc ----
    #include "foo.hh"
    const int Foo::N = 10;
----------------

But this will prevent many optimizations by the compiler, e.g. when I
compile

---- bar.cc ----
    void f() {
        int array[N];
        for (int i = 0; i < N; i++) { ... }
----------------

since the compiler doesn't know the value of N.  Is it possible to
have the constant in foo.hh, i.e. visible in all translation units
including foo.hh, without getting other problems?

I tried two other ways, both having problems:

1.  class Foo {
    public:
        static const int N;
        ...
    };
    const int Foo::N = 10;

    If I include this into multiple translation units I get multiple
    definitions of N and therefore a linker error.

2.  class Foo {
    public:
        static const int N = 10;
        ...
    };

    This seemed to work at first glance, since the compiler will
    optimize most accesses to N away and use the value directly.

    But when N is used where a reference is needed, e.g.

        some_std_list.push_back(N);

    my compiler (gcc) produces an access to N which however is not
    defined anywhere so I get a linker error again.

The traditional C way would be to use #define, but I wanted to avoid
that.  Is there way to have the constant definition in the header
file?

urs

[toc] | [next] | [standalone]


#10110

FromIan Collins <ian-news@hotmail.com>
Date2011-09-15 10:21 +1200
Message-ID<9dcnnrF784U8@mid.individual.net>
In reply to#10109
On 09/15/11 09:43 AM, Urs Thuermann wrote:
> How should one define a constant, say of type int, in a class?  The
> only way that worked for me in all cases is to delcare the constant in
> the class in the header file and define its value in the
> implementation file:
>
> ---- foo.hh ----
>      class Foo {
>      public:
>      	static const int N;
>      	...
>      };
> ---- foo.cc ----
>      #include "foo.hh"
>      const int Foo::N = 10;
> ----------------
>
> But this will prevent many optimizations by the compiler, e.g. when I
> compile
>
> ---- bar.cc ----
>      void f() {
>          int array[N];

This shouldn't compile, C++ doesn't have VLAs (yet, and they are 
optional in the new standard).

>          for (int i = 0; i<  N; i++) { ... }

This isn't really an optimisation issue, it is unlikely the compiler 
would use an immediate compare in a loop construct.

> since the compiler doesn't know the value of N.  Is it possible to
> have the constant in foo.hh, i.e. visible in all translation units
> including foo.hh, without getting other problems?
>
> I tried two other ways, both having problems:
>
> 1.  class Foo {
>      public:
>          static const int N;
>          ...
>      };
>      const int Foo::N = 10;
>
>      If I include this into multiple translation units I get multiple
>      definitions of N and therefore a linker error.

Correct.

> 2.  class Foo {
>      public:
>          static const int N = 10;
>          ...
>      };
>
>      This seemed to work at first glance, since the compiler will
>      optimize most accesses to N away and use the value directly.
>
>      But when N is used where a reference is needed, e.g.

It will work as long as the address of N isn't required.

>          some_std_list.push_back(N);
>
>      my compiler (gcc) produces an access to N which however is not
>      defined anywhere so I get a linker error again.

Correct.

> The traditional C way would be to use #define, but I wanted to avoid
> that.  Is there way to have the constant definition in the header
> file?

Use the cleaner C way: an enum constant.

enum{ N = 10 };

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10114

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-09-15 00:06 +0100
Message-ID<LNOdnYmIycHrruzTnZ2dnUVZ8mSdnZ2d@giganews.com>
In reply to#10109
On 14/09/2011 22:43, Urs Thuermann wrote:
> How should one define a constant, say of type int, in a class?  The
> only way that worked for me in all cases is to delcare the constant in
> the class in the header file and define its value in the
> implementation file:
>
> ---- foo.hh ----
>      class Foo {
>      public:
>      	static const int N;
>      	...
>      };
> ---- foo.cc ----
>      #include "foo.hh"
>      const int Foo::N = 10;
> ----------------
>
> But this will prevent many optimizations by the compiler, e.g. when I
> compile
>
> ---- bar.cc ----
>      void f() {
>          int array[N];
>          for (int i = 0; i<  N; i++) { ... }
> ----------------
>
> since the compiler doesn't know the value of N.  Is it possible to
> have the constant in foo.hh, i.e. visible in all translation units
> including foo.hh, without getting other problems?
>
> I tried two other ways, both having problems:
>
> 1.  class Foo {
>      public:
>          static const int N;
>          ...
>      };
>      const int Foo::N = 10;
>
>      If I include this into multiple translation units I get multiple
>      definitions of N and therefore a linker error.
>
> 2.  class Foo {
>      public:
>          static const int N = 10;
>          ...
>      };
>
>      This seemed to work at first glance, since the compiler will
>      optimize most accesses to N away and use the value directly.
>
>      But when N is used where a reference is needed, e.g.
>
>          some_std_list.push_back(N);
>
>      my compiler (gcc) produces an access to N which however is not
>      defined anywhere so I get a linker error again.
>
> The traditional C way would be to use #define, but I wanted to avoid
> that.  Is there way to have the constant definition in the header
> file?

Yes by using the template trick:

// constants.h
template <typename T>
struct my_constants_def
{
	static const int N;
};

template <>
const int my_constants_def<void>::N = 42;

typedef my_constants_def<void> my_constants;

// main.cpp
int main(int argc, char* argv[])
{
	std::vector<int> v;
	v.push_back(my_constants::N);
	std::cout << v[0];
}

/Leigh

[toc] | [prev] | [next] | [standalone]


#10117

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-09-15 00:16 +0100
Message-ID<RpydnVqbd4lLqOzTnZ2dnUVZ8l6dnZ2d@giganews.com>
In reply to#10114
On 15/09/2011 00:06, Leigh Johnston wrote:
> On 14/09/2011 22:43, Urs Thuermann wrote:
>> How should one define a constant, say of type int, in a class? The
>> only way that worked for me in all cases is to delcare the constant in
>> the class in the header file and define its value in the
>> implementation file:
>>
>> ---- foo.hh ----
>> class Foo {
>> public:
>> static const int N;
>> ...
>> };
>> ---- foo.cc ----
>> #include "foo.hh"
>> const int Foo::N = 10;
>> ----------------
>>
>> But this will prevent many optimizations by the compiler, e.g. when I
>> compile
>>
>> ---- bar.cc ----
>> void f() {
>> int array[N];
>> for (int i = 0; i< N; i++) { ... }
>> ----------------
>>
>> since the compiler doesn't know the value of N. Is it possible to
>> have the constant in foo.hh, i.e. visible in all translation units
>> including foo.hh, without getting other problems?
>>
>> I tried two other ways, both having problems:
>>
>> 1. class Foo {
>> public:
>> static const int N;
>> ...
>> };
>> const int Foo::N = 10;
>>
>> If I include this into multiple translation units I get multiple
>> definitions of N and therefore a linker error.
>>
>> 2. class Foo {
>> public:
>> static const int N = 10;
>> ...
>> };
>>
>> This seemed to work at first glance, since the compiler will
>> optimize most accesses to N away and use the value directly.
>>
>> But when N is used where a reference is needed, e.g.
>>
>> some_std_list.push_back(N);
>>
>> my compiler (gcc) produces an access to N which however is not
>> defined anywhere so I get a linker error again.
>>
>> The traditional C way would be to use #define, but I wanted to avoid
>> that. Is there way to have the constant definition in the header
>> file?
>
> Yes by using the template trick:
>
> // constants.h
> template <typename T>
> struct my_constants_def
> {
> static const int N;
> };
>
> template <>
> const int my_constants_def<void>::N = 42;
>
> typedef my_constants_def<void> my_constants;
>
> // main.cpp
> int main(int argc, char* argv[])
> {
> std::vector<int> v;
> v.push_back(my_constants::N);
> std::cout << v[0];
> }

Sorry I incorrectly specialized that template; I should have said:

template <typename T>
struct my_constants_def
{
	static const int N;
};

template <typename T>
const int my_constants_def<T>::N = 42;

typedef my_constants_def<void> my_constants;

/Leigh

[toc] | [prev] | [next] | [standalone]


#10125

FromJuha Nieminen <nospam@thanks.invalid>
Date2011-09-15 06:46 +0000
Message-ID<4e719f4d$0$4353$7b1e8fa0@news.nbl.fi>
In reply to#10109
Urs Thuermann <urs@isnogud.escape.de> wrote:
> How should one define a constant, say of type int, in a class?

  This actually might be considered a small defect in C++. The problem
is that if you have a public static variable, even if it's const, you
must be able to get its address, and for that it must have an actual
storage, which is why you have to define it (in addition to declaring
it inside the class declaration).

  The major defect with this is that such variable cannot be defined
as "inline", like functions can, except if your class is templated.
(I find it a bit odd that they effectively had to make static members
of template classes act as if they had been defined as "inline", out
of necessity, but they didn't extend this feature to non-templated
classes. Why not? It would be useful.)

  You could, of course, declare it outside of the class (in which case
its constness makes it a compile-time constant and hence does not
produce those linker errors about multiple definitions), but that's a
bummer because it contaminates the global (or at least the outer)
namespace, even if you name it descriptively (such as "Foo_N" in your
example).

[toc] | [prev] | [next] | [standalone]


#10133

FromMarc <marc.glisse@gmail.com>
Date2011-09-15 07:59 +0000
Message-ID<j4sb8h$a8a$1@news-rocq.inria.fr>
In reply to#10109
Urs Thuermann  wrote:

> How should one define a constant, say of type int, in a class?  The
> only way that worked for me in all cases is to delcare the constant in
> the class in the header file and define its value in the
> implementation file:
> 
> ---- foo.hh ----
>     class Foo {
>     public:
>     	static const int N;
>     	...
>     };
> ---- foo.cc ----
>     #include "foo.hh"
>     const int Foo::N = 10;
> ----------------

What happens if you move the "= 10" from where it is to the "static"
line, keeping all the rest unchanged?

[toc] | [prev] | [next] | [standalone]


#10136

FromIan Collins <ian-news@hotmail.com>
Date2011-09-15 20:09 +1200
Message-ID<9ddq53F2gmU1@mid.individual.net>
In reply to#10133
On 09/15/11 07:59 PM, Marc wrote:
> Urs Thuermann  wrote:
>
>> How should one define a constant, say of type int, in a class?  The
>> only way that worked for me in all cases is to delcare the constant in
>> the class in the header file and define its value in the
>> implementation file:
>>
>> ---- foo.hh ----
>>      class Foo {
>>      public:
>>      	static const int N;
>>      	...
>>      };
>> ---- foo.cc ----
>>      #include "foo.hh"
>>      const int Foo::N = 10;
>> ----------------
>
> What happens if you move the "= 10" from where it is to the "static"
> line, keeping all the rest unchanged?

He answered that in the part of the post you snipped....

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10139

FromMarc <marc.glisse@gmail.com>
Date2011-09-15 08:11 +0000
Message-ID<j4sbva$a8a$3@news-rocq.inria.fr>
In reply to#10136
Ian Collins  wrote:

> On 09/15/11 07:59 PM, Marc wrote:
>> What happens if you move the "= 10" from where it is to the "static"
>> line, keeping all the rest unchanged?
> 
> He answered that in the part of the post you snipped....

No, he had removed the declaration in foo.cc.

[toc] | [prev] | [next] | [standalone]


#10144

FromIan Collins <ian-news@hotmail.com>
Date2011-09-15 21:20 +1200
Message-ID<9dduauF2gmU3@mid.individual.net>
In reply to#10139
On 09/15/11 08:11 PM, Marc wrote:
> Ian Collins  wrote:
>
>> On 09/15/11 07:59 PM, Marc wrote:
>>> What happens if you move the "= 10" from where it is to the "static"
>>> line, keeping all the rest unchanged?
>>
>> He answered that in the part of the post you snipped....
>
> No, he had removed the declaration in foo.cc.

He wrote

2.  class Foo {
     public:
         static const int N = 10;
         ...
     };

N can only be initialised once.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10171

FromMarc <marc.glisse@gmail.com>
Date2011-09-15 14:03 +0000
Message-ID<j4t0ji$m64$1@news-rocq.inria.fr>
In reply to#10144
Ian Collins  wrote:

> On 09/15/11 08:11 PM, Marc wrote:
>> Ian Collins  wrote:
>>
>>> On 09/15/11 07:59 PM, Marc wrote:
>>>> What happens if you move the "= 10" from where it is to the "static"
>>>> line, keeping all the rest unchanged?
>>>
>>> He answered that in the part of the post you snipped....
>>
>> No, he had removed the declaration in foo.cc.
> 
> He wrote
> 
> 2.  class Foo {
>      public:
>          static const int N = 10;
>          ...
>      };

I said: "move". So in foo.h:
struct Foo {
  static const int N = 10;
};

and in foo.cc:
const int Foo::N;

> N can only be initialised once.

Am I initializing it several times?

[toc] | [prev] | [next] | [standalone]


#10185

FromIan Collins <ian-news@hotmail.com>
Date2011-09-16 09:32 +1200
Message-ID<9df980F2gmU16@mid.individual.net>
In reply to#10171
On 09/16/11 02:03 AM, Marc wrote:
> Ian Collins  wrote:
>
>> On 09/15/11 08:11 PM, Marc wrote:
>>> Ian Collins  wrote:
>>>
>>>> On 09/15/11 07:59 PM, Marc wrote:
>>>>> What happens if you move the "= 10" from where it is to the "static"
>>>>> line, keeping all the rest unchanged?
>>>>
>>>> He answered that in the part of the post you snipped....
>>>
>>> No, he had removed the declaration in foo.cc.
>>
>> He wrote
>>
>> 2.  class Foo {
>>       public:
>>           static const int N = 10;
>>           ...
>>       };
>
> I said: "move". So in foo.h:
> struct Foo {
>    static const int N = 10;
> };
>
> and in foo.cc:
> const int Foo::N;
>
>> N can only be initialised once.
>
> Am I initializing it several times?

I misunderstood your original post.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10191

FromMarc <marc.glisse@gmail.com>
Date2011-09-16 04:28 +0000
Message-ID<j4uj9k$dia$1@news-rocq.inria.fr>
In reply to#10185
Ian Collins  wrote:

> I misunderstood your original post.

That'll teach me to try and save time by not writing 2 lines ;-)

[toc] | [prev] | [next] | [standalone]


#10140

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-09-15 10:50 +0200
Message-ID<87d3f2xk8t.fsf@dpt-info.u-strasbg.fr>
In reply to#10109
Urs Thuermann <urs@isnogud.escape.de> writes:

> How should one define a constant, say of type int, in a class?  The
> only way that worked for me in all cases is to delcare the constant in
> the class in the header file and define its value in the
> implementation file:
>
> ---- foo.hh ----
>     class Foo {
>     public:
>     	static const int N;
>     	...
>     };
> ---- foo.cc ----
>     #include "foo.hh"
>     const int Foo::N = 10;
> ----------------
[...]

Make it a inline static method:

    class Foo {
        ...
        inline static int N() { return 10; }
        ...
    };

-- Alain.

[toc] | [prev] | [next] | [standalone]


#10143

FromIan Collins <ian-news@hotmail.com>
Date2011-09-15 21:17 +1200
Message-ID<9ddu5qF2gmU2@mid.individual.net>
In reply to#10140
On 09/15/11 08:50 PM, Alain Ketterlin wrote:
> Urs Thuermann<urs@isnogud.escape.de>  writes:
>
>> How should one define a constant, say of type int, in a class?  The
>> only way that worked for me in all cases is to delcare the constant in
>> the class in the header file and define its value in the
>> implementation file:
>>
>> ---- foo.hh ----
>>      class Foo {
>>      public:
>>      	static const int N;
>>      	...
>>      };
>> ---- foo.cc ----
>>      #include "foo.hh"
>>      const int Foo::N = 10;
>> ----------------
> [...]
>
> Make it a inline static method:
>
>      class Foo {
>          ...
>          inline static int N() { return 10; }
>          ...
>      };

The inline is unnecessary, but even without it the solution isn't valid: 
Foo::N() isn't a compile time constant.

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10151

FromAlain Ketterlin <alain@dpt-info.u-strasbg.fr>
Date2011-09-15 11:48 +0200
Message-ID<8762kuxhjk.fsf@dpt-info.u-strasbg.fr>
In reply to#10143
Ian Collins <ian-news@hotmail.com> writes:

> On 09/15/11 08:50 PM, Alain Ketterlin wrote:
>> Urs Thuermann<urs@isnogud.escape.de>  writes:

>>> How should one define a constant, say of type int, in a class?

>> Make it a inline static method:
>>
>>      class Foo {
>>          ...
>>          inline static int N() { return 10; }
>>          ...
>>      };

> The inline is unnecessary,

Sorry for the noise, but I'm used to write down as much as I can,
especially things that are optional.

> but even without it the solution isn't valid: Foo::N() isn't a compile
> time constant.

It breaks arrays (unless your compiler has anticipated the new standard)
and templates (constexpr is required in that case). I can't see any
practical case where this is a problem (and if you need to take the
address of a constant int, you're really doing something weird).

BTW, in another message someone said that the compiler is unlikely to
use an immediate in a loop compare. From:

    for ( int i=0 ; i<X::N() ; i++ )
        printf("%d\n",i);

g++ 4.4.5 on x86-64 produced:

  400720:	89 da                	mov    %ebx,%edx
  400722:	be 7c 08 40 00       	mov    $0x40087c,%esi
  400727:	bf 01 00 00 00       	mov    $0x1,%edi
  40072c:	31 c0                	xor    %eax,%eax
  40072e:	e8 75 fe ff ff       	callq  4005a8 <__printf_chk@plt>
  400733:	83 c3 01             	add    $0x1,%ebx
  400736:	83 fb 2a             	cmp    $0x2a,%ebx
  400739:	75 e5                	jne    400720 <main+0x30>

-- Alain.

[toc] | [prev] | [next] | [standalone]


#10182

FromChristopher <cpisz@austin.rr.com>
Date2011-09-15 14:24 -0700
Message-ID<55639b4f-449a-470a-9438-80577304e136@k7g2000vbd.googlegroups.com>
In reply to#10143
On Sep 15, 4:17 am, Ian Collins <ian-n...@hotmail.com> wrote:
> On 09/15/11 08:50 PM, Alain Ketterlin wrote:
>
>
>
>
>
> > Urs Thuermann<u...@isnogud.escape.de>  writes:
>
> >> How should one define a constant, say of type int, in a class?  The
> >> only way that worked for me in all cases is to delcare the constant in
> >> the class in the header file and define its value in the
> >> implementation file:
>
> >> ---- foo.hh ----
> >>      class Foo {
> >>      public:
> >>        static const int N;
> >>        ...
> >>      };
> >> ---- foo.cc ----
> >>      #include "foo.hh"
> >>      const int Foo::N = 10;
> >> ----------------
> > [...]
>
> > Make it a inline static method:
>
> >      class Foo {
> >          ...
> >          inline static int N() { return 10; }
> >          ...
> >      };
>
> The inline is unnecessary, but even without it the solution isn't valid:
> Foo::N() isn't a compile time constant.
>
> --
> Ian Collins- Hide quoted text -
>
> - Show quoted text -


Where did the OP require it to be a _compile_ time constant? He just
said constant. The FAQ leads one to believe this is the proper way to
define a constant that is accessable outside of a class, in order to
avoid the initialization fiasco. I suppose any solution to define a
_compile_ time constant does not avoid the initialization fiasco
problem, except using #define...

I do not understand the template solution proposed, what are the
internal workings that make it advantagous?

If the constant is to not be accessable outside the class, then one
would just declare a non static const member varibale and initialize
it in the initialization list.

[toc] | [prev] | [next] | [standalone]


#10184

FromIan Collins <ian-news@hotmail.com>
Date2011-09-16 09:32 +1200
Message-ID<9df975F2gmU15@mid.individual.net>
In reply to#10182
On 09/16/11 09:24 AM, Christopher wrote:
> On Sep 15, 4:17 am, Ian Collins<ian-n...@hotmail.com>  wrote:
>> On 09/15/11 08:50 PM, Alain Ketterlin wrote:
>>> Urs Thuermann<u...@isnogud.escape.de>    writes:
>>
>>>> How should one define a constant, say of type int, in a class?  The
>>>> only way that worked for me in all cases is to delcare the constant in
>>>> the class in the header file and define its value in the
>>>> implementation file:
>>
>>>> ---- foo.hh ----
>>>>       class Foo {
>>>>       public:
>>>>         static const int N;
>>>>         ...
>>>>       };
>>>> ---- foo.cc ----
>>>>       #include "foo.hh"
>>>>       const int Foo::N = 10;
>>>> ----------------
>>> [...]
>>
>>> Make it a inline static method:
>>
>>>       class Foo {
>>>           ...
>>>           inline static int N() { return 10; }
>>>           ...
>>>       };
>>
>> The inline is unnecessary, but even without it the solution isn't valid:
>> Foo::N() isn't a compile time constant.
>
> Where did the OP require it to be a _compile_ time constant?

---- bar.cc ----
     void f() {
         int array[N];
         for (int i = 0; i < N; i++) { ... }
----------------

> I do not understand the template solution proposed, what are the
> internal workings that make it advantagous?

It was unnecessarily complex.

The correct solution was the one posted by "Marc".

-- 
Ian Collins

[toc] | [prev] | [next] | [standalone]


#10186

FromLeigh Johnston <leigh@i42.co.uk>
Date2011-09-15 22:54 +0100
Message-ID<SoCdnXQnatSt6e_TnZ2dnUVZ8nadnZ2d@giganews.com>
In reply to#10184
On 15/09/2011 22:32, Ian Collins wrote:
> On 09/16/11 09:24 AM, Christopher wrote:
>> On Sep 15, 4:17 am, Ian Collins<ian-n...@hotmail.com> wrote:
>>> On 09/15/11 08:50 PM, Alain Ketterlin wrote:
>>>> Urs Thuermann<u...@isnogud.escape.de> writes:
>>>
>>>>> How should one define a constant, say of type int, in a class? The
>>>>> only way that worked for me in all cases is to delcare the constant in
>>>>> the class in the header file and define its value in the
>>>>> implementation file:
>>>
>>>>> ---- foo.hh ----
>>>>> class Foo {
>>>>> public:
>>>>> static const int N;
>>>>> ...
>>>>> };
>>>>> ---- foo.cc ----
>>>>> #include "foo.hh"
>>>>> const int Foo::N = 10;
>>>>> ----------------
>>>> [...]
>>>
>>>> Make it a inline static method:
>>>
>>>> class Foo {
>>>> ...
>>>> inline static int N() { return 10; }
>>>> ...
>>>> };
>>>
>>> The inline is unnecessary, but even without it the solution isn't valid:
>>> Foo::N() isn't a compile time constant.
>>
>> Where did the OP require it to be a _compile_ time constant?
>
> ---- bar.cc ----
> void f() {
> int array[N];
> for (int i = 0; i < N; i++) { ... }
> ----------------
>
>> I do not understand the template solution proposed, what are the
>> internal workings that make it advantagous?
>
> It was unnecessarily complex.

Not unnecessary if you want a header file only solution to a problem; my 
XML library is a header file only library but it doesn't have to 
explicitly take advantage of the template trick for defining constants 
as it is already composed of class templates.

/Leigh

[toc] | [prev] | [next] | [standalone]


#10154

FromTonyO <guinness.tony@gmail.com>
Date2011-09-15 02:50 -0700
Message-ID<6984c08f-1500-46b8-a023-bb85b3d778a3@dp9g2000vbb.googlegroups.com>
In reply to#10109
On Sep 14, 10:43 pm, Urs Thuermann <u...@isnogud.escape.de> wrote:
> How should one define a constant, say of type int, in a class?

<snip>

---- foo.hh ----
    class Foo {
    public:
        static const int N = 10; // initialise here, in declaration
        ...
    };
---- foo.cc ----
    #include "foo.hh"
    const int Foo::N; // single definition - no initialiser required
---- bar.cc ----
    #include "foo.hh"
    void f() {
        int array[Foo::N]; // remember to qualify the name when used
        for (int i = 0; i < Foo::N; i++) { ... }
----------------

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c++


csiph-web