Tom Honermann
unread,Jun 24, 2017, 7:46:19 AM6/24/17Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to Evolution Working Group mailing list, conc...@isocpp.org
The Concepts TS (N4641) states the following in 7.1.6.4 [dcl.spec.auto]
p4 (this section is now 10.1.7.4 in the WP):
"A constrained-type-specifier C1 within the declared return type of an
abbreviated function template declaration does not designate a
placeholder if its introduced constraint-expression (7.1.6.4.2) is
determined to be equivalent, using the rules in 14.6.6.1 for comparing
expressions, to the introduced constraint-expression for a
constrained-type-specifier C2 in the parameter-declaration-clause of
that function declaration. Instead, C1 is replaced by the template
parameter invented for C2 (8.3.5)."
The text includes the following example:
C const& f1(C); // has one template parameter and no deduced return type
The TS is not explicit that this behavior also applies to placeholders
specified in a trailing-return-type:
auto f1(C) -> C const&;
gcc 7.1 exhibits different behavior for placeholders specified in the
declared return type vs a trailing-return-type:
$ cat t.cpp
template<typename> concept bool C = true;
template<C> class ct {};
ct<C> af1(C) { return ct<int>{}; }
auto af2(C) -> ct<C> { return ct<int>{}; }
auto v1 = af1('c');// Rejected by gcc
auto v2 = af2('c'); // Accepted by gcc
$ g++ -c -fconcepts t.cpp
t.cpp: In instantiation of ‘ct<C> af1(auto:1) [with auto:1 = char]’:
t.cpp:5:18: required from here
t.cpp:3:31: error: could not convert ‘ct<int>{}’ from ‘ct<int>’ to
‘ct<char>’
ct<C> af1(C) { return ct<int>{}; }
^
My expectation is that the call to af2() should be similarly rejected.
Additionally, gcc does not appear to enforce the same-type constraint
when the return type consists solely of a constrained-type-specifier:
$ cat t2.cpp
template<typename> concept bool C = true;
class c {};
const C af3(C) { return 3; }
auto af4(C) -> const C { return 4; }
auto v1 = af3(c{}); // Accepted by gcc
auto v2 = af4(c{}); // Accepted by gcc
$ g++ -c -fconcepts t2.cpp
<no error>
My expectation is that both of the calls to af3() and af4() should be
rejected here.
Could someone clarify what the intent is in the Concepts TS?
Tom.