Why do we require requires requires?
One of the corners of C++20 concepts is that there are certain situations in which you have to write requires requires
. For instance, this example from [expr.prim.req]/3:
A requires-expression can also be used in a requires-clause ([temp]) as a way of writing ad hoc constraints on template arguments such as the one below:
template<typename T>
requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
The first requires introduces the requires-clause, and the second introduces the requires-expression.
What is the technical reason behind needing that second requires
keyword? Why can't we just allow writing:
template<typename T>
requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
(Note: please don't answer that the grammar requires
it)
c++ c++-concepts c++20
|
show 7 more comments
One of the corners of C++20 concepts is that there are certain situations in which you have to write requires requires
. For instance, this example from [expr.prim.req]/3:
A requires-expression can also be used in a requires-clause ([temp]) as a way of writing ad hoc constraints on template arguments such as the one below:
template<typename T>
requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
The first requires introduces the requires-clause, and the second introduces the requires-expression.
What is the technical reason behind needing that second requires
keyword? Why can't we just allow writing:
template<typename T>
requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
(Note: please don't answer that the grammar requires
it)
c++ c++-concepts c++20
3
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behindnoexcept(noexcept(...))
.
– Quentin
1 hour ago
11
Off-topic: best title ever!
– StoryTeller
1 hour ago
2
The tworequires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.
– YSC
48 mins ago
1
@YSC -co_requires
? (Sorry, couldn't resist).
– StoryTeller
22 mins ago
2
Where will the madness stop? Next thing you know, we'll havelong long
.
– Eljay
22 mins ago
|
show 7 more comments
One of the corners of C++20 concepts is that there are certain situations in which you have to write requires requires
. For instance, this example from [expr.prim.req]/3:
A requires-expression can also be used in a requires-clause ([temp]) as a way of writing ad hoc constraints on template arguments such as the one below:
template<typename T>
requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
The first requires introduces the requires-clause, and the second introduces the requires-expression.
What is the technical reason behind needing that second requires
keyword? Why can't we just allow writing:
template<typename T>
requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
(Note: please don't answer that the grammar requires
it)
c++ c++-concepts c++20
One of the corners of C++20 concepts is that there are certain situations in which you have to write requires requires
. For instance, this example from [expr.prim.req]/3:
A requires-expression can also be used in a requires-clause ([temp]) as a way of writing ad hoc constraints on template arguments such as the one below:
template<typename T>
requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
The first requires introduces the requires-clause, and the second introduces the requires-expression.
What is the technical reason behind needing that second requires
keyword? Why can't we just allow writing:
template<typename T>
requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
(Note: please don't answer that the grammar requires
it)
c++ c++-concepts c++20
c++ c++-concepts c++20
asked 1 hour ago
BarryBarry
179k18308567
179k18308567
3
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behindnoexcept(noexcept(...))
.
– Quentin
1 hour ago
11
Off-topic: best title ever!
– StoryTeller
1 hour ago
2
The tworequires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.
– YSC
48 mins ago
1
@YSC -co_requires
? (Sorry, couldn't resist).
– StoryTeller
22 mins ago
2
Where will the madness stop? Next thing you know, we'll havelong long
.
– Eljay
22 mins ago
|
show 7 more comments
3
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behindnoexcept(noexcept(...))
.
– Quentin
1 hour ago
11
Off-topic: best title ever!
– StoryTeller
1 hour ago
2
The tworequires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.
– YSC
48 mins ago
1
@YSC -co_requires
? (Sorry, couldn't resist).
– StoryTeller
22 mins ago
2
Where will the madness stop? Next thing you know, we'll havelong long
.
– Eljay
22 mins ago
3
3
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behind
noexcept(noexcept(...))
.– Quentin
1 hour ago
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behind
noexcept(noexcept(...))
.– Quentin
1 hour ago
11
11
Off-topic: best title ever!
– StoryTeller
1 hour ago
Off-topic: best title ever!
– StoryTeller
1 hour ago
2
2
The two
requires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.– YSC
48 mins ago
The two
requires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.– YSC
48 mins ago
1
1
@YSC -
co_requires
? (Sorry, couldn't resist).– StoryTeller
22 mins ago
@YSC -
co_requires
? (Sorry, couldn't resist).– StoryTeller
22 mins ago
2
2
Where will the madness stop? Next thing you know, we'll have
long long
.– Eljay
22 mins ago
Where will the madness stop? Next thing you know, we'll have
long long
.– Eljay
22 mins ago
|
show 7 more comments
3 Answers
3
active
oldest
votes
It is because the grammar requires it. It does.
A requires
constraint does not have to use a requires
expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo)
must be a legitimate requires
constraint.
A requires
expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f)
would be the beginning of a valid requires
expression.
What you want is that if you use requires
in a place that accepts constraints, you should be able to make a "constraint+expression" out of the requires
clause.
So here's the question: if you put requires (foo)
into a place that is appropriate for a requires constraint... how far does the parser have to go before it can realize that this is a requires constraint rather than a constraint+expression the way you want it to be?
Consider this:
void bar() requires (foo)
{
//stuff
}
If foo
is a type, then (foo)
is a parameter list of a requires expression, and everything in the {}
is not the body of the function but the body of that requires
expression. Otherwise, foo
is an expression in a requires
clause.
Well, you could say that the compiler should just figure out what foo
is first. But C++ really doesn't like it when the basic act of parsing a sequence of tokens requires that the compiler figure out what those identifiers mean before it can make sense of the tokens.
So yes, it's grammar.
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining whatx
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.
– Quentin
34 mins ago
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
add a comment |
I think cppreference's concepts page explains this. I can explain with "math" so to say, why this must be like this:
If you want to define a concept, you do this:
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
If you want to declare a function that uses that concept, you do this:
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
Now if you don't want to define the concept separately, I guess all you have to do is some substitution. Take this part requires (T x) { x + x; };
and replace the Addable<T>
part, and you'll get:
template<typename T> requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
which is what you're asking about.
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you havetemplate<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?
– NathanOliver
57 mins ago
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. Arequires
-as-constraint clause does not have to be arequires
-expression. That's merely one possible use of it.
– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have torequires requires
. They could have added something to the grammar to allowtemplate<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't
– NathanOliver
49 mins ago
|
show 1 more comment
Because you are saying that a thing A has a requirement B, and the requirement B has a requirement C.
The thing A requires B which in turn requires C.
The "requires" clause itself requires something.
You have thing A (requiring B (requiring C)).
Meh. :)
But according to the other answers, the first and secondrequires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of()
inrequires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).
– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54200988%2fwhy-do-we-require-requires-requires%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
It is because the grammar requires it. It does.
A requires
constraint does not have to use a requires
expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo)
must be a legitimate requires
constraint.
A requires
expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f)
would be the beginning of a valid requires
expression.
What you want is that if you use requires
in a place that accepts constraints, you should be able to make a "constraint+expression" out of the requires
clause.
So here's the question: if you put requires (foo)
into a place that is appropriate for a requires constraint... how far does the parser have to go before it can realize that this is a requires constraint rather than a constraint+expression the way you want it to be?
Consider this:
void bar() requires (foo)
{
//stuff
}
If foo
is a type, then (foo)
is a parameter list of a requires expression, and everything in the {}
is not the body of the function but the body of that requires
expression. Otherwise, foo
is an expression in a requires
clause.
Well, you could say that the compiler should just figure out what foo
is first. But C++ really doesn't like it when the basic act of parsing a sequence of tokens requires that the compiler figure out what those identifiers mean before it can make sense of the tokens.
So yes, it's grammar.
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining whatx
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.
– Quentin
34 mins ago
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
add a comment |
It is because the grammar requires it. It does.
A requires
constraint does not have to use a requires
expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo)
must be a legitimate requires
constraint.
A requires
expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f)
would be the beginning of a valid requires
expression.
What you want is that if you use requires
in a place that accepts constraints, you should be able to make a "constraint+expression" out of the requires
clause.
So here's the question: if you put requires (foo)
into a place that is appropriate for a requires constraint... how far does the parser have to go before it can realize that this is a requires constraint rather than a constraint+expression the way you want it to be?
Consider this:
void bar() requires (foo)
{
//stuff
}
If foo
is a type, then (foo)
is a parameter list of a requires expression, and everything in the {}
is not the body of the function but the body of that requires
expression. Otherwise, foo
is an expression in a requires
clause.
Well, you could say that the compiler should just figure out what foo
is first. But C++ really doesn't like it when the basic act of parsing a sequence of tokens requires that the compiler figure out what those identifiers mean before it can make sense of the tokens.
So yes, it's grammar.
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining whatx
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.
– Quentin
34 mins ago
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
add a comment |
It is because the grammar requires it. It does.
A requires
constraint does not have to use a requires
expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo)
must be a legitimate requires
constraint.
A requires
expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f)
would be the beginning of a valid requires
expression.
What you want is that if you use requires
in a place that accepts constraints, you should be able to make a "constraint+expression" out of the requires
clause.
So here's the question: if you put requires (foo)
into a place that is appropriate for a requires constraint... how far does the parser have to go before it can realize that this is a requires constraint rather than a constraint+expression the way you want it to be?
Consider this:
void bar() requires (foo)
{
//stuff
}
If foo
is a type, then (foo)
is a parameter list of a requires expression, and everything in the {}
is not the body of the function but the body of that requires
expression. Otherwise, foo
is an expression in a requires
clause.
Well, you could say that the compiler should just figure out what foo
is first. But C++ really doesn't like it when the basic act of parsing a sequence of tokens requires that the compiler figure out what those identifiers mean before it can make sense of the tokens.
So yes, it's grammar.
It is because the grammar requires it. It does.
A requires
constraint does not have to use a requires
expression. It can use any more-or-less arbitrary boolean constant expression. Therefore, requires (foo)
must be a legitimate requires
constraint.
A requires
expression (that thing that tests whether certain things follow certain constraints) is a distinct construct; it's just introduced by the same keyword. requires (foo f)
would be the beginning of a valid requires
expression.
What you want is that if you use requires
in a place that accepts constraints, you should be able to make a "constraint+expression" out of the requires
clause.
So here's the question: if you put requires (foo)
into a place that is appropriate for a requires constraint... how far does the parser have to go before it can realize that this is a requires constraint rather than a constraint+expression the way you want it to be?
Consider this:
void bar() requires (foo)
{
//stuff
}
If foo
is a type, then (foo)
is a parameter list of a requires expression, and everything in the {}
is not the body of the function but the body of that requires
expression. Otherwise, foo
is an expression in a requires
clause.
Well, you could say that the compiler should just figure out what foo
is first. But C++ really doesn't like it when the basic act of parsing a sequence of tokens requires that the compiler figure out what those identifiers mean before it can make sense of the tokens.
So yes, it's grammar.
edited 36 mins ago
answered 44 mins ago
Nicol BolasNicol Bolas
284k33468643
284k33468643
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining whatx
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.
– Quentin
34 mins ago
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
add a comment |
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining whatx
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.
– Quentin
34 mins ago
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
1
1
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
Does it make sense to have a parameter list with a type but without a name?
– NathanOliver
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining what
x
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.– Quentin
34 mins ago
This reminds me of an answer I wrote where, as far as I can tell, the compiler cannot make sense of the code before determining what
x
is. Another example is ADL working with function templates only if there's a similar function template in scope (demo), otherwise parsing fails. I am under the impression that heavy context dependence is pretty common in C++.– Quentin
34 mins ago
1
1
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
@Quentin: There are certainly cases of context-dependency in the C++ grammar. But the committee really does try to minimize that, and they definitely don't like adding more.
– Nicol Bolas
22 mins ago
add a comment |
I think cppreference's concepts page explains this. I can explain with "math" so to say, why this must be like this:
If you want to define a concept, you do this:
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
If you want to declare a function that uses that concept, you do this:
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
Now if you don't want to define the concept separately, I guess all you have to do is some substitution. Take this part requires (T x) { x + x; };
and replace the Addable<T>
part, and you'll get:
template<typename T> requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
which is what you're asking about.
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you havetemplate<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?
– NathanOliver
57 mins ago
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. Arequires
-as-constraint clause does not have to be arequires
-expression. That's merely one possible use of it.
– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have torequires requires
. They could have added something to the grammar to allowtemplate<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't
– NathanOliver
49 mins ago
|
show 1 more comment
I think cppreference's concepts page explains this. I can explain with "math" so to say, why this must be like this:
If you want to define a concept, you do this:
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
If you want to declare a function that uses that concept, you do this:
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
Now if you don't want to define the concept separately, I guess all you have to do is some substitution. Take this part requires (T x) { x + x; };
and replace the Addable<T>
part, and you'll get:
template<typename T> requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
which is what you're asking about.
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you havetemplate<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?
– NathanOliver
57 mins ago
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. Arequires
-as-constraint clause does not have to be arequires
-expression. That's merely one possible use of it.
– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have torequires requires
. They could have added something to the grammar to allowtemplate<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't
– NathanOliver
49 mins ago
|
show 1 more comment
I think cppreference's concepts page explains this. I can explain with "math" so to say, why this must be like this:
If you want to define a concept, you do this:
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
If you want to declare a function that uses that concept, you do this:
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
Now if you don't want to define the concept separately, I guess all you have to do is some substitution. Take this part requires (T x) { x + x; };
and replace the Addable<T>
part, and you'll get:
template<typename T> requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
which is what you're asking about.
I think cppreference's concepts page explains this. I can explain with "math" so to say, why this must be like this:
If you want to define a concept, you do this:
template<typename T>
concept Addable = requires (T x) { x + x; }; // requires-expression
If you want to declare a function that uses that concept, you do this:
template<typename T> requires Addable<T> // requires-clause, not requires-expression
T add(T a, T b) { return a + b; }
Now if you don't want to define the concept separately, I guess all you have to do is some substitution. Take this part requires (T x) { x + x; };
and replace the Addable<T>
part, and you'll get:
template<typename T> requires requires (T x) { x + x; }
T add(T a, T b) { return a + b; }
which is what you're asking about.
answered 1 hour ago
The Quantum PhysicistThe Quantum Physicist
11.6k64596
11.6k64596
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you havetemplate<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?
– NathanOliver
57 mins ago
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. Arequires
-as-constraint clause does not have to be arequires
-expression. That's merely one possible use of it.
– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have torequires requires
. They could have added something to the grammar to allowtemplate<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't
– NathanOliver
49 mins ago
|
show 1 more comment
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you havetemplate<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?
– NathanOliver
57 mins ago
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. Arequires
-as-constraint clause does not have to be arequires
-expression. That's merely one possible use of it.
– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have torequires requires
. They could have added something to the grammar to allowtemplate<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't
– NathanOliver
49 mins ago
2
2
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
I don't think is what the question is asking for. This is explaining the grammar, more or less.
– Passer By
57 mins ago
But why can't you have
template<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?– NathanOliver
57 mins ago
But why can't you have
template<typename T> requires (T x) { x + x; }
and require that require can be both the clause and the expression?– NathanOliver
57 mins ago
1
1
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. A
requires
-as-constraint clause does not have to be a requires
-expression. That's merely one possible use of it.– Nicol Bolas
56 mins ago
@NathanOliver: Because you're forcing the compiler to interpret one construct as another. A
requires
-as-constraint clause does not have to be a requires
-expression. That's merely one possible use of it.– Nicol Bolas
56 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@NathanOliver I don't think there's some magical answer to this. It's just ambiguous, and the compiler has certain expectations so that it parses things correctly. Probably in the next C++ version, if they find it not to be ambiguous, they can support that.
– The Quantum Physicist
52 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have to
requires requires
. They could have added something to the grammar to allow template<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't– NathanOliver
49 mins ago
@TheQuantumPhysicist What I was getting at with my comment is this answer just explains the syntax. Not what actual technical reason we have to
requires requires
. They could have added something to the grammar to allow template<typename T> requires (T x) { x + x; }
but they didn't. Barry wants to know why they didn't– NathanOliver
49 mins ago
|
show 1 more comment
Because you are saying that a thing A has a requirement B, and the requirement B has a requirement C.
The thing A requires B which in turn requires C.
The "requires" clause itself requires something.
You have thing A (requiring B (requiring C)).
Meh. :)
But according to the other answers, the first and secondrequires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of()
inrequires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).
– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
add a comment |
Because you are saying that a thing A has a requirement B, and the requirement B has a requirement C.
The thing A requires B which in turn requires C.
The "requires" clause itself requires something.
You have thing A (requiring B (requiring C)).
Meh. :)
But according to the other answers, the first and secondrequires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of()
inrequires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).
– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
add a comment |
Because you are saying that a thing A has a requirement B, and the requirement B has a requirement C.
The thing A requires B which in turn requires C.
The "requires" clause itself requires something.
You have thing A (requiring B (requiring C)).
Meh. :)
Because you are saying that a thing A has a requirement B, and the requirement B has a requirement C.
The thing A requires B which in turn requires C.
The "requires" clause itself requires something.
You have thing A (requiring B (requiring C)).
Meh. :)
answered 29 mins ago
Lightness Races in OrbitLightness Races in Orbit
286k51465788
286k51465788
But according to the other answers, the first and secondrequires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of()
inrequires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).
– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
add a comment |
But according to the other answers, the first and secondrequires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of()
inrequires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).
– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
But according to the other answers, the first and second
requires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of ()
in requires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).– Max Langhof
19 mins ago
But according to the other answers, the first and second
requires
are not conceptually the same thing (one is a clause, one an expression). In fact, if I understand correctly, the two sets of ()
in requires (requires (T x) { x + x; })
have very different meanings (the outer being optional and always containing a boolean constexpr; the inner being a mandatory part of introducing a requires expression and not allowing actual expressions).– Max Langhof
19 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
@MaxLanghof Are you saying that the requirements differ? :D
– Lightness Races in Orbit
4 mins ago
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54200988%2fwhy-do-we-require-requires-requires%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
3
Suggestion: "Is there anything that requires requires requires?". More seriously, I have a hunch that it's the same reason behind
noexcept(noexcept(...))
.– Quentin
1 hour ago
11
Off-topic: best title ever!
– StoryTeller
1 hour ago
2
The two
requires
are homonyms in my opinion: they look the same, spell the same, smell the same, but are intrinsically different. If I were to suggest a fix, I'd suggest to rename one of them.– YSC
48 mins ago
1
@YSC -
co_requires
? (Sorry, couldn't resist).– StoryTeller
22 mins ago
2
Where will the madness stop? Next thing you know, we'll have
long long
.– Eljay
22 mins ago