Представьте себе следующий код, который не компилируется:
#include <type_traits>
#include <iostream>
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;
if constexpr(std::is_same_v<decltype(x), A>)
std::cout << "A: " << x.i;
else if constexpr(std::is_same_v<decltype(x), B>)
std::cout << "B: " << x.j;
}
По этому коду я хотел иметь несколько разных веток кода для разных типов. В общем, мне нужны разные ветки не только для определенного типа, но и для любого условия constexpr.
Код выше не компилируется, потому что похоже, что этот компилятор всегда пытается скомпилировать все ветки if-constexpr, даже если они имеют ложное условие времени компиляции.
Конечно, я могу решить задачу выше, используя специализацию шаблонных структур, как в компилируемом коде ниже:
#include <type_traits>
#include <iostream>
template <size_t Id>
struct Code;
template <>
struct Code<0> {
template <typename AT>
void operator()(AT & x){
std::cout << "A: " << x.i;
}
};
template <>
struct Code<1> {
template <typename BT>
void operator()(BT & x){
std::cout << "B: " << x.j;
}
};
int main() {
struct A { int i = 123; };
struct B { int j = 456; };
B x;
Code<std::is_same_v<decltype(x), A> ? 0 : std::is_same_v<decltype(x), B> ? 1 : -1>()(x);
}
Но у последнего решения есть несколько недостатков - 1) оно гораздо более многословно, требует больше строк кода. 2) необходимо, чтобы структура кода была определена глобально, потому что структуры шаблонов могут быть определены только глобально. 3) ему нужны все необходимые аргументы для работы кода, которые будут переданы/перенаправлены на вызов operator().
Вариант constexpr выглядит намного элегантнее и более интуитивно понятен в использовании. Есть ли способ решить такую задачу с помощью if-constexpr? Чтобы заставить компилятор не компилировать ложные ветки во время компиляции.
constexpr if
может отбросить операторы, состоит в том, чтобы сделать условие зависимым от параметров шаблона, это означает, что вы не можете делать то, что пытаетесь сделать сconstexpr if
. Это не макрос, и в обязанностиconstexpr if
не входит отбрасывание всех операторов. - person Nicol Bolas   schedule 30.12.2020