Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I declare a concept at class scope?

Consider this code:

struct A
{
    template <typename T>
    concept foo = true;
};

It doesn't compile. My Clang 10 gives me error: concept declarations may only appear in global or namespace scope, and GCC says something similar.

Is there a reason why it's not allowed? I don't see why it couldn't work, even if the enclosing class was a template.

like image 601
HolyBlackCat Avatar asked Oct 07 '20 20:10

HolyBlackCat


People also ask

How do you declare a concept in C++?

Let's define a few concepts in this post. A concept can be defined by a function template or by a variable template. A variable template is new with C++14 and declares a family of variables. If you use a function template for your concept, it's called a function concept; in the second case a variable concept.

What is scope in C++?

When you declare a program element such as a class, function, or variable, its name can only be "seen" and used in certain parts of your program. The context in which a name is visible is called its scope. For example, if you declare a variable x within a function, x is only visible within that function body.

How do you declare a class without definition?

It is possible to declare a class without defining it (forward declaration) as long as it is defined later on within the translation unit. In the case of functions, one can declare a function without defining it within the translation unit, and the linker will link it to its definition in a different translation unit.


Video Answer


1 Answers

The fundamental difficulty that would arise is that concepts could become dependent:

template<class T>
struct A {
  template<T::Q X>
  void f();
};

Is X a non-type template parameter of (dependent) type T::Q (which does not require typename in C++20), or is it a type template parameter constrained by the concept T::Q?

The rule is that it’s the former; we would need new syntax (along the lines of typename/template) to express the other possibility: perhaps something like

template<T::concept Q X> requires T::concept R<X*>
void A::g() {}

No one has explored such an extension seriously, and it could easily conflict with other extensions to concept syntax that might be more valuable.

like image 136
Davis Herring Avatar answered Oct 16 '22 10:10

Davis Herring