On Thu, Jan 6, 2022 at 7:58 PM Arthur O'Dwyer <arthur.j.odwyer@gmail.com> wrote:
On Thu, Jan 6, 2022 at 11:13 AM Михаил Найденов via Std-Proposals <std-proposals@lists.isocpp.org> wrote:
Hello,
The title says it all, consider:

template<class T>
concept stuff_as_members = requires {
  typename T::type;
  T::template templ<int>();
};

struct C
{
  using type = int;

  template<class T>
  static void templ() {}
};

template<stuff_as_members T> //< constrained type!
void func()
{
  T::type val;     //< typename should NOT be needed, type is known to be a typename
  
  T::templ<int>(); //< template should NOT be needed, templ is known to be a template
}

int main()
{
  func<C>();
}

Can we do this for good?


 
I would guess not, because remember `typename` and `template` are hints to the parser — nothing to do with semantic analysis. So the parser knows that the token sequence
    template < stuff_as_members T >
is introducing a constrained template, but it's not going to go analyze `concept stuff_as_members` to find out what its requirements are.

That looks like an area of improvement to me - if we can use the concept beyond syntactical checks to improve the code, we should do so. 
For example

template<stuff_as_members T> 
void func()
{
  T::type += 1;     
}
 
Could be caught right in definition time, rather than instantiation time, catching the error as early as possible.

(It might not even be allowed to do that, because the concept might have default arguments that would need to be instantiated, and so on.

Also, there is a GCC (extension / bug) in this area, where `typename T::type` triggers lookup as a type and `T::type` triggers lookup as a non-type, and they both can succeed:
I believe there's at least one place in the paper standard where this kind of "restricted" lookup is actually mandated (although this simple case is not it; I'd call this a GCC bug). You'd want to check whether your proposal would change the semantics of that kind of thing.

Can the look-up really change (in an undesired way), considering the compiler will simply have to "insert the keywords", based on the names, found in the concept?
 

Basically, anything that messes with name lookup is a bad idea, and needs motivation stronger than "hey we could do this." The motivation should be, like, "We should do this because..." (and then insert something really compelling).

Because the code should not literally break if one changes a concrete type to a parameterized type, as it does today, aiming for Bjarne's "Generic programming is just programming" overarching goal. 
 

HTH,
Arthur