https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91073

            Bug ID: 91073
           Summary: if constexpr no longer works directly with Concepts
           Product: gcc
           Version: 9.1.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: rwdougla at gmail dot com
  Target Milestone: ---

It appears I can no longer use a Concept within the if-constexpr's expression.
I receive the error:
<source>:26:58: error: expected unqualified-id before ')' token

Compiler Explorer link: https://godbolt.org/z/r8TXSM

Assuming it is not due to an intended change in concepts for c++20, as Clang
appears to support it when compiled with concepts branch:
https://godbolt.org/z/4liykV

Workaround exists by assigning Concept evaluation to a constexpr bool and using
that in the if-constexpr check.

In case Compiler Explorer link is insufficient, here is gcc params:
Using:
gcc 9.1.0
flags: -std=c++2a -fconcepts -O2 -Wall -Wextra -Werror -Wpedantic -Wconversion

Code:
#include <iostream>

template<typename T, typename... Params>
concept HasInit = requires(T t, Params... p) { t.init(p...); };

struct Initable { void init(int) { std::cout << "In init" << std::endl; } };
struct Createable { void create(int) { std::cout << "In create" << std::endl; }
};

struct Foo{
    template<typename CB>
    void for_each(CB&& cb)
    {
        Initable i;
        Createable c;
        cb(i);
        cb(c);
    }

    Foo()
    {
        struct Bar { int x; };
        for_each(
            [&](auto& foo){
                // constexpr bool has_init = HasInit<decltype(foo), int>;
                // if constexpr (has_init)
                if constexpr (HasInit<decltype(foo), int>)
                {
                    foo.init(5);
                }
            });
    }
};

int main()
{
    Foo f;
    return 0;
}

Reply via email to