Ich habe Schwierigkeiten, consExpr im Kontext eines C++ - eingebauten mehrdimensionalen Arrays zu verstehen. Das folgende Beispiel veranschaulicht mein Problem.consExpr + Multidimension Array schlägt fehl
a) Wenn ich einen Wert zur Kompilierzeit suche, funktioniert das so, wie ich es erwarte, solange ich ihm nichts zuordne.
b) Aber wenn ich versuche, es einer anderen constexpr-Variable zuzuweisen, erhalte ich einen Kompilierzeitfehler.
Ich habe mich umgesehen und sogar das Standarddokument überprüft. Jeder, der mir das erklären kann, ist wirklich ein Guru. FWIW, ich kompiliere dies mit CLang 8.1 unter Xcode mit C++ 14 aktiviert.
using uint8_t = unsigned char;
#if 1
enum class safe_numerics_error : uint8_t {
success = 0,
failure, // result is above representational maximum
error_count
};
#else
// avoiding enum class fails to solve problem
struct safe_numerics_error {
const uint8_t m_t;
constexpr const static uint8_t success = 0;
constexpr const static uint8_t failure = 1;
constexpr safe_numerics_error(uint8_t t) :
m_t(t)
{}
constexpr operator uint8_t() const {
return m_t;
}
};
#endif
template<typename R>
struct checked_result {
const safe_numerics_error m_e;
const union {
const R m_r;
char const * const m_msg;
};
constexpr /*explicit*/ checked_result(const R & r) :
m_e(safe_numerics_error::success),
m_r(r)
{}
constexpr /*explicit*/ checked_result(const safe_numerics_error & e) :
m_e(e),
m_msg("")
{}
};
// integers addition
template<class T>
constexpr inline checked_result<T> operator+(
const checked_result<T> & t,
const checked_result<T> & u
){
// "Constexpr variable 'e' must be initialized by a constant expression"
constexpr const safe_numerics_error x[2][2]{
// t == success
{
// u == ...
safe_numerics_error::success,
safe_numerics_error::failure
},
// t == positive_overflow_error,
{
// u == ...
safe_numerics_error::failure,
safe_numerics_error::failure
}
};
#if 1 // compile fails
constexpr const safe_numerics_error e = x
[static_cast<uint8_t>(t.m_e)]
[static_cast<uint8_t>(u.m_e)]
;
return
(safe_numerics_error::success == e)
? t.m_r + u.m_r
: checked_result<T>(e)
;
#else // works as expected
return
safe_numerics_error::success == x
[static_cast<uint8_t>(t.m_e)]
[static_cast<uint8_t>(u.m_e)]
? t.m_r + u.m_r
: checked_result<T>(x
[static_cast<uint8_t>(t.m_e)]
[static_cast<uint8_t>(u.m_e)]
)
;
#endif
}
int main(){
constexpr const checked_result<unsigned> i = 0;
constexpr const checked_result<unsigned> j = 0;
constexpr const checked_result<unsigned> k = i + j;
// return k.m_r;
constexpr const checked_result<unsigned> i2 = safe_numerics_error::failure;
constexpr const checked_result<unsigned> j2 = 0;
constexpr const checked_result<unsigned> k2 = i2 + j2;
return k2.m_r;
}
Was ist der Fehler? In welcher Zeile? – user463035818
ist der Code, den Ihr Compiler nicht sehen wird (in den '# else' Blöcken) nur Rauschen oder ein Teil der Frage? – user463035818
Zwei Kommentare dazu: 1) Sie geben m_r am Ende von main im Fehlerfall zurück, der ungültig ist, da das Objekt mit einem Fehler konstruiert wurde. 2) Warum nicht einfach & die Enum-Werte anstelle eines 2D-Arrays? d. h. Erfolg & Erfolg == Erfolg, aber Fehler & alles = Fehler – budjmt