Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > const or not const, that's the question here! :-)

Reply
Thread Tools

const or not const, that's the question here! :-)

 
 
Adem24
Guest
Posts: n/a
 
      06-13-2008
The compiler which I have to use in a project doesn't like
the following construct. It says: 'bitset' : invalid template argument.
It means that it wants only a static-like const N as a template argument,
ie. it doesn't accept a const variable that was initialized
from an auto variable (here i), for passing it as a template
argument to bitset<n>.

Is this a compiler limitation or is my code not standard conform?
Can you think of any workaround construct to achieve this
or an alternate functionality with such a compiler?

Of course if I change the line to read for example
const size_t N = 1U << 16;
then it compiles ok. But I need to loop 22 times here...

#include <bitset>
void f()
{
for (size_t i = 1; i <= 22; ++i)
{
const size_t N = 1U << i;
bitset<N> bv;

bv.set(7);
//...
}
}

 
Reply With Quote
 
 
 
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      06-13-2008
Adem24 wrote:

> The compiler which I have to use in a project doesn't like
> the following construct. It says: 'bitset' : invalid template argument.
> It means that it wants only a static-like const N as a template argument,
> ie. it doesn't accept a const variable that was initialized
> from an auto variable (here i), for passing it as a template
> argument to bitset<n>.
>
> Is this a compiler limitation or is my code not standard conform?
> Can you think of any workaround construct to achieve this
> or an alternate functionality with such a compiler?
>
> Of course if I change the line to read for example
> const size_t N = 1U << 16;
> then it compiles ok. But I need to loop 22 times here...
>
> #include <bitset>
> void f()
> {
> for (size_t i = 1; i <= 22; ++i)
> {
> const size_t N = 1U << i;
> bitset<N> bv;


Your code is wrong. This N is not a compile time constant. Templates only
work with those.

You might want to have a look into dynamic_bitset from boost or
vector<bool>.


> bv.set(7);
> //...
> }
> }



Best

Kai-Uwe Bux
 
Reply With Quote
 
 
 
 
Eric Pruneau
Guest
Posts: n/a
 
      06-13-2008

"Adem24" <(E-Mail Removed)> a écrit dans le message de news:
g2ug98$533$(E-Mail Removed)...
> The compiler which I have to use in a project doesn't like
> the following construct. It says: 'bitset' : invalid template argument.
> It means that it wants only a static-like const N as a template argument,
> ie. it doesn't accept a const variable that was initialized
> from an auto variable (here i), for passing it as a template
> argument to bitset<n>.
>
> Is this a compiler limitation or is my code not standard conform?
> Can you think of any workaround construct to achieve this
> or an alternate functionality with such a compiler?
>
> Of course if I change the line to read for example
> const size_t N = 1U << 16;
> then it compiles ok. But I need to loop 22 times here...
>
> #include <bitset>
> void f()
> {
> for (size_t i = 1; i <= 22; ++i)
> {
> const size_t N = 1U << i;
> bitset<N> bv;
>
> bv.set(7);
> //...
> }
> }
>


Your code cannot compile. N must be a compile time evaluatable constant. In
your case, N is constant but unknow to the compiler at compile time because
of i.

----------------
Eric Pruneau


 
Reply With Quote
 
kwikius
Guest
Posts: n/a
 
      06-13-2008

"Kai-Uwe Bux" <(E-Mail Removed)> wrote in message
news:g2ugif$5as$(E-Mail Removed)...
> Adem24 wrote:
>
>> The compiler which I have to use in a project doesn't like
>> the following construct. It says: 'bitset' : invalid template argument.
>> It means that it wants only a static-like const N as a template argument,
>> ie. it doesn't accept a const variable that was initialized
>> from an auto variable (here i), for passing it as a template
>> argument to bitset<n>.
>>
>> Is this a compiler limitation or is my code not standard conform?
>> Can you think of any workaround construct to achieve this
>> or an alternate functionality with such a compiler?
>>
>> Of course if I change the line to read for example
>> const size_t N = 1U << 16;
>> then it compiles ok. But I need to loop 22 times here...
>>
>> #include <bitset>
>> void f()
>> {
>> for (size_t i = 1; i <= 22; ++i)
>> {
>> const size_t N = 1U << i;
>> bitset<N> bv;

>
> Your code is wrong. This N is not a compile time constant. Templates only
> work with those.


You could probably set this up fairly simply to use compile time recursion.
Use a functor templated on N which calls N-1 and specialize it for zero (or
other way up ) case etc...

regards
Andy Little


 
Reply With Quote
 
Kai-Uwe Bux
Guest
Posts: n/a
 
      06-13-2008
kwikius wrote:

>
> "Kai-Uwe Bux" <(E-Mail Removed)> wrote in message
> news:g2ugif$5as$(E-Mail Removed)...
>> Adem24 wrote:
>>
>>> The compiler which I have to use in a project doesn't like
>>> the following construct. It says: 'bitset' : invalid template argument.
>>> It means that it wants only a static-like const N as a template
>>> argument, ie. it doesn't accept a const variable that was initialized
>>> from an auto variable (here i), for passing it as a template
>>> argument to bitset<n>.
>>>
>>> Is this a compiler limitation or is my code not standard conform?
>>> Can you think of any workaround construct to achieve this
>>> or an alternate functionality with such a compiler?
>>>
>>> Of course if I change the line to read for example
>>> const size_t N = 1U << 16;
>>> then it compiles ok. But I need to loop 22 times here...
>>>
>>> #include <bitset>
>>> void f()
>>> {
>>> for (size_t i = 1; i <= 22; ++i)
>>> {
>>> const size_t N = 1U << i;
>>> bitset<N> bv;

>>
>> Your code is wrong. This N is not a compile time constant. Templates only
>> work with those.

>
> You could probably set this up fairly simply to use compile time
> recursion. Use a functor templated on N which calls N-1 and specialize it
> for zero (or other way up ) case etc...


Yes one could do that. But why? You end up with some monstrous incantation
that will fill your screen with book size error messages if you get a tiny
detail wrong; and for which gain? The algorithms underlying bitset<N> are
mostly just bit fiddling iterated over a vector of unsigned long (int?)
anyway. I would be rather surprised if it matters performancewise whether
the length of that buffer is fixed at compile time or at run time.

I love templates, I really do; but in a case like this, I think they would
make the code worse (e.g., harder to maintain and change).


Best

Kai-Uwe Bux
 
Reply With Quote
 
kwikius
Guest
Posts: n/a
 
      06-14-2008
On Jun 13, 10:42*pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
> kwikius wrote:
>
> > "Kai-Uwe Bux" <(E-Mail Removed)> wrote in message
> >news:g2ugif$5as$(E-Mail Removed)...
> >> Adem24 wrote:

>
> >>> The compiler which I have to use in a project doesn't like
> >>> the following construct. It says: 'bitset' : invalid template argument..
> >>> It means that it wants only a static-like const N as a template
> >>> argument, ie. it doesn't accept a const variable that was initialized
> >>> from an auto variable (here i), for passing it as a template
> >>> argument to bitset<n>.

>
> >>> Is this a compiler limitation or is my code not standard conform?
> >>> Can you think of any workaround construct to achieve this
> >>> or an alternate functionality with such a compiler?

>
> >>> Of course if I change the line to read for example
> >>> * *const size_t N = 1U << 16;
> >>> then it compiles ok. But I need to loop 22 times here...

>
> >>> #include <bitset>
> >>> void f()
> >>> {
> >>> * * for (size_t i = 1; i <= 22; ++i)
> >>> * * * {
> >>> * * * * const size_t N = 1U << i;
> >>> * * * * bitset<N> bv;

>
> >> Your code is wrong. This N is not a compile time constant. Templates only
> >> work with those.

>
> > You could probably set this up fairly simply to use compile time
> > recursion. Use a functor templated on N which calls N-1 and specialize it
> > for zero (or other way up ) case etc...

>
> Yes one could do that. But why?


Only one way to find out....

<... usual inertia elided ...>

regards
Andy Little

 
Reply With Quote
 
Andy Little
Guest
Posts: n/a
 
      06-14-2008
kwikius wrote:
> On Jun 13, 10:42 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>> kwikius wrote:


>>> You could probably set this up fairly simply to use compile time
>>> recursion. Use a functor templated on N which calls N-1 and specialize it
>>> for zero (or other way up ) case etc...

>> Yes one could do that. But why?

>
> Only one way to find out....
>
> <... usual inertia elided ...>


Apologies That was a bit fierce, however using compile time loop
unrolling is a useful technique, and the OP was asking why it wasnt
didnt seem possible. I was merely pointing out that it is possible. In
some cases the compiler may do loop unrolling for you, but doing it
explicitly using compile time recursion is one less uncertainty/ layer
of complexity for the optimiser.

Interestingly, looking at std::bitset, Its kind of a weird hybrid
because the length is fixed but many ops are runtime.

As an example one could add a bitset.flip<Pos>() function to accompany
bitset.flip(pos). The first version being again easier to optimise and
all the information re the op is available at compile time unlike the
runtime parameter, and very usefully, the range can be checked at
compile time too, so there is no need of a runtime check and possible
exception, unlike appears to be the case in the runtime flip (which
throws an exception on out of range). The same applies to many (probably
nearly all) ops in bitset AFAICS.

regards
Andy Lttle


 
Reply With Quote
 
Frank Birbacher
Guest
Posts: n/a
 
      06-14-2008
Hi!

kwikius schrieb:
> You could probably set this up fairly simply to use compile time recursion.
> Use a functor templated on N which calls N-1 and specialize it for zero (or
> other way up ) case etc...


You could probably fix this fairly simple by using the same size in each
loop:

const size_t maxlen = 22;
bitset<1 << maxlen> bv;
for (size_t i = 1; i <= maxlen; ++i)
{
const size_t N = 1U << i;

bv.set(7);
//...
}

Frank
 
Reply With Quote
 
Bo Persson
Guest
Posts: n/a
 
      06-14-2008
Andy Little wrote:
> kwikius wrote:
>> On Jun 13, 10:42 pm, Kai-Uwe Bux <(E-Mail Removed)> wrote:
>>> kwikius wrote:

>
>>>> You could probably set this up fairly simply to use compile time
>>>> recursion. Use a functor templated on N which calls N-1 and
>>>> specialize it for zero (or other way up ) case etc...
>>> Yes one could do that. But why?

>>
>> Only one way to find out....
>>
>> <... usual inertia elided ...>

>
> Apologies That was a bit fierce, however using compile time loop
> unrolling is a useful technique, and the OP was asking why it wasnt
> didnt seem possible. I was merely pointing out that it is possible.
> In some cases the compiler may do loop unrolling for you, but doing
> it explicitly using compile time recursion is one less uncertainty/
> layer of complexity for the optimiser.
>
> Interestingly, looking at std::bitset, Its kind of a weird hybrid
> because the length is fixed but many ops are runtime.
>
> As an example one could add a bitset.flip<Pos>() function to
> accompany bitset.flip(pos). The first version being again easier
> to optimise and all the information re the op is available at
> compile time unlike the runtime parameter, and very usefully, the
> range can be checked at compile time too, so there is no need of a
> runtime check and possible exception, unlike appears to be the case
> in the runtime flip (which throws an exception on out of range).
> The same applies to many (probably nearly all) ops in bitset AFAICS.
>


Any decent optimizer can do that anyway, when pos is a compile time
constant. That saves you from modifying the application code when that
condition changes.


Bo Persson


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
const vector<const MyType> Vs const vector<MyType> magnus.moraberg@gmail.com C++ 2 02-09-2009 10:45 PM
is const necessary in eg int compar(const void *, const void *) lovecreatesbeauty@gmail.c0m C Programming 26 11-10-2008 09:47 PM
const correctness - should C++ prefer const member over non-const? fungus C++ 13 10-31-2008 05:33 AM
const vector<A> vs vector<const A> vs const vector<const A> Javier C++ 2 09-04-2007 08:46 PM
Casting int'** to 'const int * const * const' dosn't work, why? Jonas.Holmsten@gmail.com C Programming 11 07-01-2007 06:16 PM



Advertisments