1

Following code compiles fine:

template <bool X>
struct A;

template <>
struct A<true> {
  int x = 1;
};

template <>
struct A<false> {
};

template <bool X>
void f()
{
  A<X> a;
  if constexpr (X) {
    if (a.x == 1)
      ;
  }
}

int main()
{
  f<false>();
}

Inside the function f() the code for X==true is indeed valid because a.x exists in this case. In any case, f() is instantiated for X==false only.

A slightly different code, however does not compile:

template <bool X>
struct A;

template <>
struct A<true> {
  int x = 1;
};

template <>
struct A<false> {
};

void f()
{
  static constexpr bool X = false;
  A<X> a;
  if constexpr (X) {
    if (a.x == 1)
      ;
  }
}

int main()
{
  f();
}

The error is:

test.cpp:18:11: error: ‘struct A<false>’ has no member named ‘x’
   18 |     if (a.x == 1)

I fail to see the concrete difference in calling f<false>() with the first code, and f() with the second code.

Why does the compiler refuse the second code?

francesco
  • 7,189
  • 7
  • 22
  • 49
  • the false branch in `constexpr if` is only discarded inside templates. When `f` is not a template then all branches of the `constexpr if` must be valid. I'd expect that there are dupilcates... – 463035818_is_not_an_ai Jun 19 '23 at 11:03
  • not sure what is the right standardese wording, cppref says ["Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive: "](https://en.cppreference.com/w/cpp/language/if), ie it is discarded, but it is *checked* when not insided a template – 463035818_is_not_an_ai Jun 19 '23 at 11:15

0 Answers0