1

I have some code which tries to use a concept to specify requirements on the member functions of a class:

#include <type_traits>

template <typename A>
concept MyConcept = requires(A a, bool b) {
  { a.one() } -> bool;
  a.two();
  a.three(b);
};   

Unfortunately, clang 10.0.0 using -std=c++20 on https://godbolt.org produces an error:

<source>:5:18: error: expected concept name with optional arguments [clang-diagnostic-error]

  { a.one() } -> bool;

                 ^

Does anyone have a handle on the syntax clang is expecting? I've tried a number of variants based on samples from various sources, such as this Compound Requirements sample, but no luck so far:

#include <type_traits>

template<typename T> concept C2 =
requires(T x) {
    {*x} -> std::convertible_to<typename T::inner>; // the expression *x must be valid
                                                    // AND the type T::inner must be valid
                                                    // AND the result of *x must be convertible to T::inner
    {x + 1} -> std::same_as<int>; // the expression x + 1 must be valid 
                               // AND std::same_as<decltype((x + 1)), int> must be satisfied
                               // i.e., (x + 1) must be a prvalue of type int
    {x * 1} -> std::convertible_to<T>; // the expression x * 1 must be valid
                                       // AND its result must be convertible to T
};

Any help appreciated.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • 1
    Seems like it needs a metafunction on the right side: `{ a.one() } -> std::same_as;`. Exactly as example says. :-) – oakad Sep 09 '20 at 04:37
  • Yes, the syntax was changed in the proposal a while ago. – Acorn Sep 09 '20 at 08:07
  • the sample, using the metafunction, also gives me the `expected concept name with optional arguments` error when i run it on godbolt using x86-64 clang 10.0.0 with -std=c++20. – Bob Pretzker Sep 09 '20 at 13:57

1 Answers1

0

The concepts proposal changed and now it requires using std::same_as.

This compiles fine with Clang 10 (although you may need to provide std::same_as yourself if you don't have a stdlib with it):

template <typename A>
concept MyConcept = requires(A a, bool b) {
  { a.one() } -> std::same_as<bool>;
  a.two();
  a.three(b);
};

struct SomeType {
  bool one() { return true; }
  void two() {}
  void three(bool) {}
};

bool foo(MyConcept auto a) {
  return a.one();
}

void bar() {
  foo(SomeType());
}
Acorn
  • 24,970
  • 5
  • 40
  • 69
  • i have tried the std::same_as but in my configuration and on godbolt i continue to see the "expected concept name with optional arguments" error. – Bob Pretzker Sep 09 '20 at 14:05
  • here is a link to what I'm seeing: [godbolt](https://godbolt.org/z/5f37f6). – Bob Pretzker Sep 09 '20 at 14:11
  • As the answer says, you need to provide `std::same_as` yourself because your standard library does not include it. See for instance cppreference or https://stackoverflow.com/questions/58509147/why-does-same-as-concept-check-type-equality-twice for one – Acorn Sep 09 '20 at 14:26
  • 1
    I see.. thanks for your help. Here is updated [godbolt](https://godbolt.org/z/e5bvT1) with a custom same_as implementation based on the case you cite - hopefully it adequately subsumes the ambiguity :). – Bob Pretzker Sep 09 '20 at 14:52
  • 1
    You're welcome! Hopefully in a few weeks/months we will have the concepts library implemented and released by both libstdc++ and libc++ and it will be easier :-) – Acorn Sep 09 '20 at 16:46
  • Can you elaborate on the concepts proposal changes? I noticed that `std::is_same` is now the only concept defined in the libc++ header and I'm having trouble finding information about the change. – mousebyte Feb 24 '21 at 23:58