admin管理员组

文章数量:1379411

Consider the following code:

enum { a = 1, b = 2 - a};

void foo() {
    if constexpr(a == 1) { }
    else { static_assert(b != 1, "fail :-("); }
}

naively, one might expect the static_assert() to never be triggered, since the if constexpr condition holds. But - it is triggered (GodBolt).

What C++ mechanism should I use instead, to ensure failure only when the condition of an if statement evaluates to false?

Consider the following code:

enum { a = 1, b = 2 - a};

void foo() {
    if constexpr(a == 1) { }
    else { static_assert(b != 1, "fail :-("); }
}

naively, one might expect the static_assert() to never be triggered, since the if constexpr condition holds. But - it is triggered (GodBolt).

What C++ mechanism should I use instead, to ensure failure only when the condition of an if statement evaluates to false?

Share Improve this question edited Mar 18 at 20:53 Bergi 666k161 gold badges1k silver badges1.5k bronze badges asked Mar 18 at 15:31 einpoklumeinpoklum 133k80 gold badges421 silver badges864 bronze badges 4
  • 2 static_assert(a == 1 || b != 1, "fail :-("); Since a static_assert isn't scoped in this case (... because it is static and not in a template), so doesn't matter that it is in the else block. – Eljay Commented Mar 18 at 21:57
  • @Eljay: I "don't know" about a as I write the static asseration, or whatever alternative I use. Also, DRY. – einpoklum Commented Mar 18 at 22:07
  • How can I create a type-dependent expression that is always false? – 許恩嘉 Commented Mar 18 at 23:44
  • 1 AFAIK if constexpr has no meaning outside a template. It's purpose is to eliminate the branching when the template is instantiated (hence the need to have a constexpr condition). In your case, it's equivalent to a regular if but restricted to constexpr conditions only (which is then useless). – Fareanor Commented Mar 19 at 9:41
Add a comment  | 

1 Answer 1

Reset to default 1

What C++ mechanism should I use instead, to ensure failure only when the condition of an if statement evaluates to false?

According to cppreference

Outside a template, a discarded statement is fully checked. if constexpr is not a substitute for the #if preprocessing directive:

so I suppose you can make your foo() function a template one

template <int = 0>
void foo() {
    if constexpr(a == 1) { }
    else { static_assert(b != 1, "Fail"); }
}

--- EDIT ---

The OP asks

it's quite problematic to change the function definition just for an assertion somewhere... can't I use some kind of templated gadget instead?

I don't see a way through a type trait.

But if you can use at least C++20, so template lambdas, you can wrap your code inside a template lambda defined inside the foo() function. And call the lambda.

I mean something as follows

enum { a = 1, b = 2 - a};

void foo() {
  auto l = []<int = 0>{
    if constexpr (a == 1) {
    }
    else {
      static_assert(b != 1, "fail :-(");
    }
  };

  l();
}

int main ()
{
  foo();
}

本文标签: