Using the return value of a constexpr function as a parameter for another function

I have a function constexprthat computes a CRC32 hash from a string literal.

template <size_t len>
constexpr uint32_t ctcrc32(const char (&str)[len]) {
    return detail::crc32<len - 2>(str) ^ 0xFFFFFFFF;
}

(it refers to other functions constexpr)

What I want to do is call another function that takes a value uint32_tand uses it to access data in some unordered_map. Such a call is as follows:

uniformByNameCRC32(ctcrc32("uPointLight.position"));

I expect the hash hash "uPointLight.position"will be computed once at build time, and then the resulting constant is passed to uniformByNameCRC32(), but it is not, and ctcrc32 () is called at runtime, which basically kills the CPU, since I have a lot of calls uniformByNameCRC32().

This, however, works just fine:

std::array<uint64_t, ctcrc32("string_literal")> array;

, ctcrc32() constexpr.

?

+4
3

constrexpr:

constexpr auto value = ctcrc32("uPointLight.position")
uniformByNameCRC32(value);
+2

OP ( )

,

, , ctcrc32 .

template <uint32_t N>
constexpr uint32_t getCV () // get constexpr value
 { return N; }

uniformByNameCRC32(getCV<ctcrc32("uPointLight.position")>());

ctcrc32() getCV() .

+3

, ++ . ++ ++ . ( , , , , , : " " ".

constexpr , , , .

There are zero basic C ++ compilers that are called new types at runtime. So, we have the ability to force something to run at compile time; at we have template constants:

template<uint32_t v>
std::integral_constant< uint32_t, v > kint32{};

With this we can do:

uniformByNameCRC32(kint32<ctcrc32("uPointLight.position")>);

should execute ctcrc32at compile time. Not doing this will require a lot of compiler work.

AT you can even do:

template<auto x>
std::integral_constant< std::decay_t<decltype(x)>, x > k{};

and it works for any type.

std::integral_constant in turn, implicitly converts back to a value of the same type.

+3
source

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


All Articles