Forced compilation of constexpr

In C ++ 11 we get constexpr :

 constexpr int foo (int x) { return x + 1; } 

Is it possible to make foo calls with dynamic x value of compile-time error? That is, I want to create foo so that you can only pass constexpr arguments.

+6
source share
3 answers

Replace it with a metaphone:

 template <int x> struct foo { static constexpr int value = x + 1; }; 

Using:

 foo<12>::value 
+8
source

Unfortunately, there is no way to guarantee that the constexpr function, even the most trivial one, will be evaluated by the compiler if absolutely necessary. That is, if it does not appear in the place where its value is required at compile time, for example, in a template. To force the compiler to evaluate at compile time, you can do the following:

 constexpr int foo_implementation (int x) { return x + 1; } #define foo(x) std::integral_constant<int, foo_implementation(x)>::value 

and then use foo in your code as usual

 int f = foo(123); 

The best part about this approach is that it guarantees a compile-time estimate, and you get a compilation error if you pass the foo runtime variable:

 int a = 2; int f = foo(a); /* Error: invalid template argument for 'std::integral_constant', expected compile-time constant expression */ 

Itโ€™s not so nice that it requires a macro, but it seems inevitable if you want both a guaranteed estimate of compilation time and beautiful code. (I wish it were wrong, though!)

+2
source

I would use static_assert as shown in this example

 #include<iostream> constexpr int foo(int x) { return x+1; } int main() { // Works since its static std::cout << foo(2) << std::endl; static_assert(foo(2) || foo(2) == 0, "Not Static"); // Throws an compile error int in = 3; std::cout << foo(in) << std::endl; static_assert(foo(in) || foo(in) == 0, "Not Static"); } 

For more information: http://en.cppreference.com/w/cpp/language/static_assert

0
source

Source: https://habr.com/ru/post/949498/


All Articles