Constante de matriz no se evalúa como constante a pesar de que solo se llaman funciones constexpr en la inicialización.
Este es una versión simplificada y reproducible de mi código:
type_id.h
template<typename>
void type_id() {}
typedef void(*type_id_t)();
c_sort.h
(basado en esta respuesta)
template<typename array="">
constexpr void c_sort_impl(Array& array) noexcept {
using size_type = typename Array::size_type;
size_type gap = array.size();
bool swapped = false;
while ((gap > size_type{ 1 }) or swapped) {
if (gap > size_type{ 1 }) {
gap = static_cast<size_type> (gap / 1.247330950103979);
}
swapped = false;
for (size_type i = size_type{ 0 }; gap + i < static_cast<size_type> (array.size()); ++i) {
if (array[i] > array[i + gap]) {
auto swap = array[i];
array[i] = array[i + gap];
array[i + gap] = swap;
swapped = true;
}
}
}
}
template<typename array="">
constexpr Array c_sort(Array array) noexcept {
auto sorted = array;
c_sort_impl(sorted);
return sorted;
}
foo.h
#include "type_id.h"
#include "c_sort.h"
#include <array>
template<class... cs="">
struct Foo
{
constexpr static auto key =
c_sort(std::array<type_id_t, sizeof...(cs)="">{ type_id<cs>... });
};
Si intento instanciar Foo
, obtengo un error del compilador que me dice “la expresión no se evaluó a una constante”. ¿Por qué sucede esto? Al inicializar key
, solo llamo a funciones marcadas con constexpr
. ¿Qué parte de la expresión no se puede evaluar en tiempo de compilación?</type_id_t,></class…>
davy.ai
El problema con la instancia de
Foo
es que el constructor destd::array
no esconstexpr
hasta C++20, por lo que la creación del objetostd::array
dentro de la inicialización dekey
enFoo
no puede evaluarse en tiempo de compilación si estás utilizando un compilador que no soporta C++20. Por lo tanto, la expresión en su conjunto no puede ser evaluada en tiempo de compilación, a pesar de que todas las funciones llamadas están marcadas comoconstexpr
.