1

This is a reduced example of a bigger function. The core issue is that at one point I try to get the value out of a constexpr std::variant via a constexpr/consteval function. This fails and I do not know why.

Code:

#include <type_traits>
#include <variant>

constexpr auto f2(const auto& a_variant)
{
    if (std::is_constant_evaluated())
        return std::get<a_variant.index()>(a_variant);
    else
        return 0;
}

consteval auto f3(const auto& a_variant)
{
    return std::get<a_variant.index()>(a_variant);
}

void f()
{
    constexpr auto v = std::variant<int, double>{1};

    // works
    [[maybe_unused]] constexpr auto r = std::get<v.index()>(v);

    // fails
    constexpr auto r2 = f2(v);
    constexpr auto r3 = f3(v);
}

Result:

... error: 'a_variant' is not a constant expression 7 | return std::get<a_variant.index()>(a_variant); ...

https://godbolt.org/z/4156oo5Gf

  • 2
    parameters are not `constexpr`, even in `consteval`. – Jarod42 Sep 15 '22 at 07:56
  • std::get<>(variant) is a constexpr function (calling other constexpr functions) itself. f2/f3 just add a level of indirection. – std_unordered_map Sep 15 '22 at 08:02
  • it would work if `index()` was a static function, but since it is not, it depends on the parameter object, which is not a compile time constant. [constexpr condition not constant?](https://stackoverflow.com/questions/53599431/constexpr-condition-not-constant) – Stack Danny Sep 15 '22 at 08:06
  • The gcc implementation of std::get<>(variant) also calls variant.index(). – std_unordered_map Sep 15 '22 at 08:20

0 Answers0