11

Given the following code:

constexpr int omg() { return 42; }

const int a = omg(); // NOT guaranteed to be evaluated at compile time

constexpr const int a = omg(); // guaranteed to be evaluated at compile time

Is there a way to force something to be evaluated at compile time without assigning it to something constexpr (or in a compile time context like a template parameter ot enum shenanigans)?

Something like this:

const int a = force_compute_at_compile_time(omg());

perhaps something like this (which doesn't compile - I'm not much into constexpr yet):

template<typename T> constexpr T force_compute_at_compile_time(constexpr const T& a) { return a; }
onqtam
  • 4,356
  • 2
  • 28
  • 50

1 Answers1

12

You could use non-type template arguments:

template <int N> constexpr int force_compute_at_compile_time();

const int a = force_compute_at_compile_time<omg()>();

Since N is a template argument, it has to be a constant expression.

TartanLlama
  • 63,752
  • 13
  • 157
  • 193
  • And is it possible to deduce that ```int``` from the expression? I'm looking for a general purpose wrapper that can force any constexpr function to be evaluated at compile time - not just the ones returning int – onqtam Oct 06 '16 at 07:10
  • Doesn't this only work for integral values? – Albjenow Oct 06 '16 at 07:10
  • It'll only work for types which can be used as non-type template parameters, so integral types, references, pointers, enums and pointers to member. The `int` can be deduced in C++17, but before that you'd need to add another template parameter and do `force_compute_etc();`. – TartanLlama Oct 06 '16 at 07:17
  • 1
    @TartanLlama So even with the decltype stuff if it is returning a constexpr custom string class - it wouldn't be possible - because it's not usable as a non-type template parameter? sad... – onqtam Oct 06 '16 at 07:21