Showing posts with label cpp17_constexpr. Show all posts
Showing posts with label cpp17_constexpr. Show all posts

Jul 23, 2021

[C++] consteval in C++17

Reference:
https://andreasfertig.blog/2021/07/cpp20-a-neat-trick-with-consteval/

What consteval does:
As the name of the keyword tries to imply, it forces a constant evaluation.
In the standard, a function that is marked as consteval is called an immediate function.
The keyword can be applied only to functions/function template.
Immediate here means that the function is evaluated at the front-end, yielding only a value, which the back-end uses.
Such a function never goes into your binary.
A consteval-function must be evaluated at compile-time or compilation fails.
With that, a consteval-function is a stronger version of constexpr-functions.



template <auto value>
inline constexpr auto as_constant = value;

constexpr int Calc(int x) { return 4 * x; }

int main() {
    auto res = as_constant<Calc(2)>;
    ++res;
}

Jan 14, 2018

[c++17] [clang] force Clang to run constexpr function at compile time

#include <iostream>

constexpr int factorial(int n) {
     return n <= 1 ? 1 : (n * factorial(n - 1));
}

constexpr int fibonacci(unsigned n) {
    return n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

int main() {
    std::cout << factorial(5) << '\n';
    std::cout << fibonacci(10) << '\n';
}
to:
int main() {
    constexpr int a = factorial(12);
    constexpr int b = fibonacci(10);
  
    // Check if the values are actually calculated at compile time
   static_assert(a == 479001600, "factorial failed\n");
   static_assert(b == 55, "fibonacci failed\n");
     
   std::cout << a << '\n'; 
   std::cout << b << '\n';
}

Oct 4, 2016

[c++] [cppcon2016] Constant fun

enum  bm { b0 = 0x1, b1 = 0x2, b2 = 0x4 };
int b = bm::b0 | bm::b1;

//---
enum  bm { b0 = 0x1, b1 = 0x2, b2 = 0x4 };
bm b = bm::b0 | bm::b1; // bad conversion

//--
enum  bm { b0 = 0x1, b1 = 0x2, b2 = 0x4 };

bm b = bm(bm::b0 | bm::b1); //OK

//--
enum class bm { b0 = 0x1, b1 = 0x2, b2 = 0x4 };
bm b = bm(bm::b0 | bm::b1); // no such op!!

//--
enum class bm { b0 = 0x1, b1 = 0x2, b2 = 0x4 };

constexpr bm operator| (bm v0, bm v1) {
return bm(int(v0) | int(v1));
}

bm b = bm::b0 | bm::b1;

switch (b) {
case bm::b0 | bm::b1: /*...*/; // OK due to constexpr operator
}

//--