[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 --- Comment #8 from Younan Zhang --- Sorry for duplicate comments. Network issue :( And thanks Patrik's explaination.
[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 --- Comment #7 from Younan Zhang --- (In reply to Patrick Palka from comment #4) > (In reply to Younan Zhang from comment #2) > > (In reply to Patrick Palka from comment #1) > > > #1 is neither a non-template friend declaration with a requires-clause > > > nor a > > > friend function template with a constraint that depends on a template > > > parameter from an enclosing template, so it seems to me [temp.friend]/9 > > > doesn't apply here? > > > > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to > > template where `Us` depends on parameter from outter C? > > ```cpp > > template > > friend auto factory(const C Us&...);` > > ``` > > And IIUC if we desugar the type-constraint C... we get > > ```cpp > template requires (C && ...) > friend auto factory(const Us&...); > ``` > > so the friend doesn't have a constraint that depends on an outer template > parameter (Ts) Oh I see. I thought C was the template parameter, which should be a concept.
[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 --- Comment #6 from Younan Zhang --- (In reply to Patrick Palka from comment #4) > (In reply to Younan Zhang from comment #2) > > (In reply to Patrick Palka from comment #1) > > > #1 is neither a non-template friend declaration with a requires-clause > > > nor a > > > friend function template with a constraint that depends on a template > > > parameter from an enclosing template, so it seems to me [temp.friend]/9 > > > doesn't apply here? > > > > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to > > template where `Us` depends on parameter from outter C? > > ```cpp > > template > > friend auto factory(const C Us&...);` > > ``` > > And IIUC if we desugar the type-constraint C... we get > > ```cpp > template requires (C && ...) > friend auto factory(const Us&...); > ``` > > so the friend doesn't have a constraint that depends on an outer template > parameter (Ts) Oh I see. I thought C was the template parameter, which should be a concept.
[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 Younan Zhang changed: What|Removed |Added Status|UNCONFIRMED |RESOLVED Resolution|--- |INVALID --- Comment #5 from Younan Zhang --- (In reply to Patrick Palka from comment #4) > (In reply to Younan Zhang from comment #2) > > (In reply to Patrick Palka from comment #1) > > > #1 is neither a non-template friend declaration with a requires-clause > > > nor a > > > friend function template with a constraint that depends on a template > > > parameter from an enclosing template, so it seems to me [temp.friend]/9 > > > doesn't apply here? > > > > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to > > template where `Us` depends on parameter from outter C? > > ```cpp > > template > > friend auto factory(const C Us&...);` > > ``` > > And IIUC if we desugar the type-constraint C... we get > > ```cpp > template requires (C && ...) > friend auto factory(const Us&...); > ``` > > so the friend doesn't have a constraint that depends on an outer template > parameter (Ts) Oh I see. I thought C was the template parameter, which should be a concept.
[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 --- Comment #3 from Younan Zhang --- (In reply to Younan Zhang from comment #2) > (In reply to Patrick Palka from comment #1) > > #1 is neither a non-template friend declaration with a requires-clause nor a > > friend function template with a constraint that depends on a template > > parameter from an enclosing template, so it seems to me [temp.friend]/9 > > doesn't apply here? > > I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to > template where `Us` depends on parameter from outter C? > ```cpp > template > friend auto factory(const C Us&...);` > ``` typo: friend auto factory(const Us&...);
[Bug c++/108884] [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 --- Comment #2 from Younan Zhang --- (In reply to Patrick Palka from comment #1) > #1 is neither a non-template friend declaration with a requires-clause nor a > friend function template with a constraint that depends on a template > parameter from an enclosing template, so it seems to me [temp.friend]/9 > doesn't apply here? I'm a bit confused. Doesn't `friend auto factory(const C auto&...)` equal to template where `Us` depends on parameter from outter C? ```cpp template friend auto factory(const C Us&...);` ```
[Bug c++/108884] New: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope?
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108884 Bug ID: 108884 Summary: [temp.friends]/9: Should constraint friends declared in class scope differ with definition out of scope? Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: zyn7109 at gmail dot com Target Milestone: --- Clang implements deferred concept instantiation in [D126907](https://reviews.llvm.org/D126907). As that patch suggests, according to [temp.friend]/9, > A friend function template with a constraint that depends on a > template parameter from an enclosing template shall be a definition. > Such a constrained friend function or function template declaration > does not declare the same function or function template as a > declaration in any other scope. That being said, such code should not compile as constrained friend declaration (#1) doesn't declare the function defined out of class scope (#2). (Example comes from https://github.com/clangd/clangd/issues/1511) ```cpp // https://gcc.godbolt.org/z/sP9xdTqhe template concept C = true; template class Foo { private: Foo(const Ts&...) {}; public: friend auto factory(const C auto&...); // #1 }; auto factory(const C auto&... ts) // #2 { return Foo{ts...}; } int main() { factory(5); } ``` Such code is rejected in Clang 16 onwards, showing that function defined at #2 is trying to access private constructor of `Foo`, but GCC still accepts this, which implies GCC considers #1 and #2 are the same function. Is this a GCC regression or I have missed something from the wording? Note that if we swap #1 and #2, i.e., ```cpp // https://gcc.godbolt.org/z/WfG7vnxx8 template concept C = true; template class Foo { private: Foo(const Ts&...) {} public: friend auto factory(const C auto&... ts) { return Foo{ts...}; } }; template auto factory(const C auto&... ts) -> Foo; int main() { factory(5); } ``` then both GCC and Clang would accept it.
[Bug libstdc++/104465] std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465 --- Comment #6 from Younan Zhang --- (In reply to Jonathan Wakely from comment #4) > But the reason that it accepts the argument is that it's an lvalue. > > You tested std::ranges::viewable_range> but you > should have tested std::ranges::viewable_range&>. (In reply to Jonathan Wakely from comment #5) > An lvalue vector has always been a viewable range. Yes you're right. `foo(v)` will return 1 now: ```cpp template int foo(T) requires std::ranges::viewable_range { return 1; } int foo(auto) { return 0; } ``` I also tested `auto(v) | std::views::reverse` and GCC rejects with: ``` ...required for the satisfaction of 'viewable_range<_Range>': note: no operand of the disjunction is satisfied... ``` (In reply to Jonathan Wakely from comment #5) > That's just because Clang is broken and doesn't work with any libstdc++ views: https://github.com/llvm/llvm-project/issues/44178 looks subtle ;) Thanks for your detailed answer~
[Bug libstdc++/104465] std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465 --- Comment #1 from Younan Zhang --- * link typo for Clang 13 demo: https://gcc.godbolt.org/z/f7Eb53zb5
[Bug libstdc++/104465] New: std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b)
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104465 Bug ID: 104465 Summary: std::vector should satisfy std::ranges::viewable_range (P2415 for -c++2b) Product: gcc Version: 12.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: zyn7109 at gmail dot com Target Milestone: --- Given the following code, ```cpp #include #include #include #include int foo(std::ranges::viewable_range auto) { return 1; } // #1 int foo(auto) { return 0; } // #2 int main() { const std::vector v {"1", "2", "3", "4"}; std::cout << foo(v) << " "; for (auto vv: v | std::views::reverse) std::cout << vv << " "; // #3 } ``` compiling with GCC 12.0.1 (20220208) (https://wandbox.org/permlink/aPZzDSVF0wbtUQF8), the output is "0 4 3 2 1" rather than "1 4 3 2 1" since the overload resolution selects #2 for `foo`. However, as P2415 was merged into C++23 (https://github.com/cplusplus/papers/issues/1085), `std::vector` is now a `viewable_range` and with Clang 15, "1 4 3 2 1" is the result. (https://wandbox.org/permlink/8uzBa0Ot6Yj22Z0l). It seems that P2415 is still not implemented for libstdc++ yet. However, GCC accepts #3 since range was introduced from GCC 10.x (I'm not quite sure which version) while considering `std::ranges::viewable_range> == false`. As the cppreference (https://en.cppreference.com/w/cpp/ranges/reverse_view) or C++20 draft suggests (24.7.1 [range.adaptor.object]/1, https://timsong-cpp.github.io/cppwp/n4861/range.adaptors#range.adaptor.object-1), the range adaptor `std::views::reverse` only takes `viewable_range` as arguments. So it makes me confused and I wonder if I missed something. Clang 13 rejects the above code (https://gcc.godbolt.org/z/xoKesEz7q), which is as expected.