Reputation: 31
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.
Upvotes: 3
Views: 221
Reputation: 473407
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.
Upvotes: 2