Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is this a BUG about the <concept> lib in c++?

I've met an "internal compiler error" while learning the concept lib in c++...

Environment:

compile cmd: g++ -std=c++17 test.cpp -fconcepts -g -v| more;

some of the compile output:

Thread model: posix
gcc version 8.1.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
COLLECT_GCC_OPTIONS='-std=c++17' '-fconcepts' '-g' '-v' '-save-temps' '- 
shared-libgcc' '-mtune=core2' '-march=nocona'

my codes:

template<class A, class B>
concept bool Test = true;

template<class T>
concept bool Ohh = requires(T t, Test<typename T::type> sth){
    { t.func(sth) };
};

//this one works well !!
// template<class T>
// concept bool OK = requires(T t){
//  { t.func(Test<typename T::type>) };
// };

template<class T>
struct A{
    typedef T type;

    void func(T){}
};

Ohh{T} /* OK{T} works fine */
struct B{
    static const bool value = true;
};

int main(int argc, char *argv[] /*, char *envp[]*/)
{
    cout << B<A<int>>::value;
}

Here are the error msgs:

internal compiler error: in synthesize_implicit_template_parm, at cp/parser.c:39068
 concept bool Ohh = requires(T t, Test<typename T::type> sth){
                                                       ^
libbacktrace could not find executable to open.
...

Is that a bug or I just shouldn't use Test<typename T::type> in requires-expression's parameter list?

Note: I cannot report this bug because account creation is restricted on buggzilla.

like image 411
AnotherRegister Avatar asked Dec 08 '25 09:12

AnotherRegister


1 Answers

Any internal compiler error is a de-facto compiler bug. The question is, should your code be valid if the compiler were working correctly?

No.

Test<typename T::type> is a constexpr boolean variable, which ultimately boils down to the value true. And a variable is not a legal typename inside of the parameters of a requires expression.

What you want in the parameter is just typename T::type, since that's the type you want to give sth. But what you also want is to restrict this concept to a T which has a ::type typename member.

Basically, you don't need Test:

template<class T>
    requires requires { T::type; }
concept bool Ohh = requires(T t, typename T::type sth){
    { t.func(sth) };
};

Or, if you want to conceptualize the idea of a type which has a ::type typename:

template<class T>
concept bool HasType = requires { T::type; };

template<HasType T>
concept bool Ohh = requires(T t, typename T::type sth){
    { t.func(sth) };
};

I think you're falling into the trap of pre-concepts thinking, where you've tried to use the usual template metaprogramming solution instead of the concept one. Express the requirement you want as directly as possible.

like image 74
Nicol Bolas Avatar answered Dec 10 '25 22:12

Nicol Bolas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!