I have no idea how the compiler decides what can be a constant and what can't. It's clear that the expression being assigned to the bool is constexpr, because it seems to have no problem returning idx - 1, so the compiler knows it's a constant expression. I don't get this:
#include <tuple>
#include <cstdint>
#include <cstdio>
#include <array>
template <typename type, typename ... among_Ts>
consteval auto index_of_type() -> uint64_t
{
uint64_t idx = 0;
// CANNOT BE CONSTEXPR EVEN THOUGH IT IS CONSTEXPR
// REMOVING constexpr MAKES IT COMPILE. AND THIS FUNCTION IS CONSTEVAL
constexpr bool bFound = ((++idx, std::is_same_v<type, among_Ts>) || ...);
return idx - 1;
}
template <typename type, typename ... var_types>
consteval auto index_of_tyoe_in_tuple(const std::tuple<var_types...>&) -> uint64_t
{
return index_of_type<type, var_types...>();
}
int main(int argc, char* argv[])
{
constexpr std::tuple<int, double, char> my_tuple;
constexpr int idx = index_of_tyoe_in_tuple<double>(my_tuple);
}
I can't do static_assert(bFound) if I don't make bFound constexpr.
Edit: I can't even do:
if constexpr (idx > 20) to check that way. So it says that idx > 20 isn't a constexpr, and yet the return idx - 1 actually is consteval. Weird.
Edit: Oh my god even if I put it inside another function it still doesn't work:
template <typename type, typename ... among_Ts>
consteval auto index_of_type() -> uint64_t
{
uint64_t idx = 0;
static_assert(sizeof ... (among_Ts) > 1);
auto lambda = [=] <typename type_, typename ... amont_Ts_>() consteval mutable -> uint64_t
{
((++idx, std::is_same_v<type, among_Ts>) || ...);
return idx;
};
// STILL CAN'T BE CONSTEXPR WHY?????
constexpr uint64_t idx_of_type = lambda.template operator() < type, among_Ts... > ();
return idx_of_type - 1;
}
idxan unsequenced expression? If so, the line is UB and compiler has to reject it asconstexpr. I'm not entirely sure since they are chained with operators with well defined precedence, so might not be the case.static constexpr, orconstexprin namespace scope, then you have decided that it is evaluated at compile time.