constexpr question

Andy Gibbs andyg1001@hotmail.co.uk
Thu Jun 9 16:24:00 GMT 2011


On Thursday, June 09, 2011 2:52 PM, Jonathan Wakely wrote:

>> The question I have is: why doesn't (or can't) the second case work? In
>> function 'test2' the compiler believes 'a' is a constant expression and 
>> the
>> declaration of variable 'two' shows 'wrapper' can take a constexpr as its
>> template parameter, so is it just an oversight of the compiler that 
>> 'test3'
>> doesn't compile? Or is it intentional?
>
> I'm not certain, but I think the compiler's right.  A constexpr
> function isn't one which can *only* be a constant expression, it's one
> which is potentially a constant-expression when used in the right
> context (e.g. given only constants as arguments.)
>
> You can call test1 and test2 with non-constant arguments, and they act
> like normal functions. Or you can call them with constants and they
> can appear in constant expressions.  test3 cannot be used like a
> normal function.

Jonathan,

Thanks for your reply.  I think that you're right that the compiler is 
probably working according to the logic you have suggested.  Maybe it is a 
overlooked feature in the proposed new standard.  I believe it isn't 
necessarily the case that you'd always want a constexpr function that also 
can be used as a normal (run-time) function since it may implement an 
algorithm suitable (i.e. possible) for compile-time use but unsuitable (i.e. 
inefficient) for run-time use.  The idea, of course, would be to implement 
two different functions, one for use at compile-time, one for use at 
run-time.  The problem for me is how to stop my users using the compile-time 
(i.e. inefficient) function at run-time.  My experience is that 
documentation is often not enough!  If it had worked, my wrapper idea would 
have been perfect: it would have stopped the compile-time function being 
used accidentally at run-time because the parameter wouldn't be constexpr 
and couldn't therefore be a template parameter; and the user would otherwise 
be able to decide whether to use the compile-time or the run-time function 
as he wished.

>> I understand that test3 would not compile if passed a non-constexpr
>> parameter, whereas test2 would compile -- but this is what I would want:
>> this way I can stop test3 being used except during compile-time. Or is
>> there a better way of doing this?
>
> Make the int parameter a template parameter, so it has to be known at
> compile-time.
>
> template<int A>
>   constexpr int test3()
>   { return wrapper<test1(A)>::value; }
>
> constexpr int three = test3<one>();

Yes, this would work, but I'm afraid defeats the aim I'm trying to acheive. 
;o)

Cheers
Andy




More information about the Gcc-help mailing list