Template--Parameter bei Aufruf des Elternkonstruktors in C++
-
Ok, also das Concept funktioniert vom Prinzip her so wie oben geschrieben. Das Problem ist einfach, dass es eine Art zeitige Auswertung des static_assert zu geben scheint. Lasse ich das weg, funktioniert es:
// template<typename Left_t, typename Right_t> concept supports_left_right = requires(Left_t left, Right_t right) { gte::TIQuery<Real_t, Left_t, Right_t>()(left, right).intersect; }; // template<typename Left_t, typename Right_t> inline bool is_collision(const Left_t& left, const Right_t& right) { if (has_points_inside(left, right)) return true; if constexpr (supports_left_right<Left_t, Right_t>) { gte::TIQuery<Real_t, Left_t, Right_t> query; return query(left, right).intersect; } else { gte::TIQuery<Real_t, Right_t, Left_t> query; return query(right, left).intersect; } }
-
@Pellaeon Die Sache mit dem
static_assert
wurde hier im Thread schonmal angesprochen. Siehe dazu auch diese Bemerkungen zu constexpr if:Note: the discarded statement can't be ill-formed for every possible specialization:
template<typename T> void f() { if constexpr (std::is_arithmetic_v<T>) // ... else static_assert(false, "Must be arithmetic"); // ill-formed: invalid for every T }
The common workaround for such a catch-all statement is a type-dependent expression that is always false:
template<class> inline constexpr bool dependent_false_v = false; template<typename T> void f() { if constexpr (std::is_arithmetic_v<T>) // ... else static_assert(dependent_false_v<T>, "Must be arithmetic"); // ok }
Der
static_assert
-Ausdruck muss vom Template-Parameter abhängig sein, damit es nicht ausgewertet wird.
-
@Finnegan stiiiiimmt. Das ist halt der Unterschied zw. Kurz- und Langzeitgedächtnis Danke für die Erinnerung! Faktisch klappt es ja aber auch mit der verkürzten Variante. Entweder <left, right> geht, dann geht er da rein, ansonsten probiert er es hart im else-Zweig. Und wenn das auch nicht geht. Ist das ja dann auch ein Compilefehler.
-
@Pellaeon sagte in Template--Parameter bei Aufruf des Elternkonstruktors in C++:
Ist das ja dann auch ein Compilefehler.
Die würde ich auch immer bevorzugen, sofern sie verständlich genug sind (ist ja in den letzten Jahren deutlich besser geworden) und die Alternative lauten würde, den Code zu verkomplizieren (Wartungskosten).