Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are types allowed to be specified for return-type-requirement in a requires expression?

Look at this simple concept example:

template <typename T>
requires requires(T t) { { t+t } -> bool; }
void fn() {
}

int main() {
    fn<bool>();
}

Here, I used bool as the type-constraint of return-type-requirement. The current draft says:

type-constraint:

nested-name-specifier opt concept-name

nested-name-specifier opt concept-name < template-argument-list opt >

So type-constraint must be a concept-name. Is bool (or any type) allowed as a concept name? If yes, what does it mean, and where does the draft standard allow it? I'd think that as bool is not a concept, so this is not allowed. Yet, both gcc and clang compile my example: godbolt

(Of course, it makes sense to allow types, I just don't see where the standard allows this, and what it means exactly: should types match exactly? Or conversions can happen?)

like image 341
geza Avatar asked Sep 02 '19 04:09

geza


1 Answers

Is bool (or any type) allowed as a concept name?

No, bool (or any type) are not concepts. They are types.

The original design, and the Concepts TS, did allow types. That is, you could write a compound requirement like:

{ E } -> int;

But this was removed from C++20 by P1452R2. There were a number of reasons this was removed, one of the motivations being what it would interfere with a future direction of wanting to adopt a generalized form of auto, like vector<auto> or vector<Concept>.

What the type requirement allowed you to express, you already can anyway, by whichever of:

{ E } -> std::same_as<int>;
{ E } -> std::convertible_to<int>;

was intended. Which also answers your question of what the type requirement actually meant - matching exactly or allowing conversions.

like image 73
Barry Avatar answered Nov 17 '22 01:11

Barry