Date: Wed, 2 Oct 2019 01:11:30 -0400
1. "const" overloads happen all the time in order to keep an identical
qualifier in case your "return * this".
2. Because if you can propagate "constexpr" then you can take full
advantage of reserved compile-time functions.
qualifier in case your "return * this".
2. Because if you can propagate "constexpr" then you can take full
advantage of reserved compile-time functions.
-- *Phil Bouchard* Founder C.: (819) 328-4743 Fornux Logo <http://www.fornux.com> On 10/2/19 1:04 AM, Mingxin Wang wrote: > > > 1. Will it be able to deduce the "this" qualifier? > > No, but why? I do not think it necessary to have such overloads in a > class. > > > 2. Can the "constexpr" become a qualifier your way? (Because > "constexpr" is just a compile-time "const" that cannot be casted away). > > No, but again, why? > > The motivation for `qualification_type` and `reference_type` is the > PFA, introduced in P0957. However, I do not think the two requirements > above are universal programming models that should be supported by the > language, unless there are convincing motivating use cases. > > *From:*Phil Bouchard <phil_at_[hidden]> > *Sent:* Wednesday, October 2, 2019 12:39 PM > *To:* Mingxin Wang <mingxwa_at_[hidden]>; > std-proposals_at_[hidden]; Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> > *Subject:* Re: [std-proposals] Template qualifiers > > Interesting but: > > 1. Will it be able to deduce the "this" qualifier? > > struct A > > { > > A & get() { return * this; } > > A const & get() const { return * this; } > > A volatile & get() volatile { return * this; } > > A const volatile & get() const volatile { return * this; } > > }; > > 2. Can the "constexpr" become a qualifier your way? (Because > "constexpr" is just a compile-time "const" that cannot be casted away). > > -- > > *Phil Bouchard* > Founder > C.: (819) 328-4743 > > Fornux Logo > <https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.fornux.com&data=02%7C01%7Cmingxwa%40microsoft.com%7Ce7be00b6b79e40c9c7bd08d746f26b46%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C1%7C637055879330054127&sdata=3YoGr3bSSUD5pTF71ZyPExLU%2FGldra1Pn0vRcgqDiaQ%3D&reserved=0> > > On 10/1/19 10:25 PM, Mingxin Wang wrote: > > I believe there are certain metaprogramming requirements in > qualification & reference computation, and a library solution was > already proposed in P0957 > <https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.open-std.org%2Fjtc1%2Fsc22%2Fwg21%2Fdocs%2Fpapers%2F2019%2Fp0957r2.pdf&data=02%7C01%7Cmingxwa%40microsoft.com%7Ce7be00b6b79e40c9c7bd08d746f26b46%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C1%7C637055879330064138&sdata=CtbGc3%2BfbWD5FtYAh%2FgWCgMHLek66YeE1VYMXV3Ab9Y%3D&reserved=0>(section > 7.1 & 7.2) to support complex type computation required by the > PFA, which is a solution for non-intrusive polymorphism. > > I think there is no need to add a language feature for > qualification & reference computation because enumeration + type > traits would be sufficient, as proposed in P0957: > > enum class qualification_type > > { none, const_qualified, volatile_qualified, cv_qualified }; > > enum class reference_type { lvalue, rvalue }; > > template <class T, qualification_type Q> using add_qualification_t > = …; > > template <class T> inline constexpr qualification_type > qualification_of_v = …; > > template <class T, reference_type R> using add_reference_t = …; > > *From:*Std-Proposals <std-proposals-bounces_at_[hidden]> > <mailto:std-proposals-bounces_at_[hidden]>*On Behalf Of *Phil > Bouchard via Std-Proposals > *Sent:* Wednesday, October 2, 2019 1:56 AM > *To:* Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> > <mailto:arthur.j.odwyer_at_[hidden]>; std-proposals_at_[hidden] > <mailto:std-proposals_at_[hidden]> > *Cc:* Phil Bouchard <phil_at_[hidden]> <mailto:phil_at_[hidden]> > *Subject:* Re: [std-proposals] Template qualifiers > > [I apologize for my mistakes, I wrote the email very quickly] > > 2 things here: > > 1. "constexpr" would ideally need to be treated like a qualifier. > This way it could propagate like cv qualifier. > > template<class U> > struct construct { > template<class QT, class T = std::remove_cvref_t<QT&&>, class > = std::enable_if_t<std::is_same_v<T, U>>> > QT&& operator()(node_proxy&, QT&& po) { > return T(po); > } > }; > > struct node_proxy {}; > > node_proxy __x; > > struct ConstClass > > { > constexpr ConstClass() {} > }; > > > struct NonConstClass > > { > NonConstClass() {} > }; > > // This will result in: > construct<ConstClass>()(__x, ConstClass()); // constexpr expression > construct<NonConstClass>()(__x, NonConstClass()); // not a > constexpr expression > > 2. The "qualifier" template token would be: > > - the only way to qualify the "this" parameter; > > - syntactic sugar: > > template<class T> > struct construct { > template<qualifier Q1, qualifier Q2> > Q1 T&& operator()(node_proxy&, Q1 T&& po) Q2 { > return T(po); > } > }; > > // This will result in: > construct<ConstClass> c1() > > c1(__x, ConstClass()); // constexpr expression > > construct<NonConstClass> volatile const c2() > > c2(__x, NonConstClass()); // not a constexpr expression from an > arbitrary "volatile const" object > > -- > > *Phil Bouchard* > Founder > C.: (819) 328-4743 > > Fornux Logo > <https://nam06.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww.fornux.com&data=02%7C01%7Cmingxwa%40microsoft.com%7Ce7be00b6b79e40c9c7bd08d746f26b46%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C1%7C637055879330064138&sdata=ooR7LW%2FIfKk9mRfe%2Bh6N6gEpUAd9CXMF4%2B%2BmTfoY9bc%3D&reserved=0> > > On 9/30/19 9:51 AM, Arthur O'Dwyer wrote: > > On Sun, Sep 29, 2019 at 4:51 PM Phil Bouchard via > Std-Proposals <std-proposals_at_[hidden] > <mailto:std-proposals_at_[hidden]>> wrote: > > > > [Please CC my personal email address in the replies > otherwise I'll can't properly follow-up] > > > > So let's take a better example: > > > > template <typename T> > > struct construct<T> { > > // Let the compiler generate the most efficient code > > template <qualifier Q> > > inline T Q operator()(node_proxy & __y, T Q po) { > > return T(po); > > } > > }; > > > > struct ConstClass { > > constexpr ConstClass() {} > > }; > > > > struct NonConstClass { > > NonConstClass() {} > > }; > > > > // This will result in: > > construct<ConstClass>()(ConstClass()); // constexpr expression > > construct<NonConstClass>()(NonConstClass()); // not a > constexpr expression > > Well, I see two or three factual errors here, plus one or two > fundamental errors. > 1. `construct<ConstClass>()(ConstClass())` will not compile as > written, because `operator()` takes two parameters, not one. > You didn't provide any argument corresponding to parameter `__y`. > 2. `construct<ConstClass>()(ConstClass())` will not be a > compile-time constant, because you didn't mark `operator()` as > constexpr. (Remember, the `constexpr` keyword on a function > already means "conditionally constexpr"! You don't need any > special tricks to achieve conditional constexpr-ness.) > > 3. You wrote `template<typename T> construct<T>` as if it were > a partial specialization, but I'm going to assume that was a typo. > > 4. An rvalue of type `T` is not convertible to a return type > of `T &`, nor to `volatile T &&`. Do you think this is a > problem for your code? > > 5 (fundamental). You still seem to be assuming that `Q` can > deduce as "none." Please, consider the ramifications of > permitting a template that can deduce either `foo(const int& > i)` or `foo(int i)`. Please understand that that overload set > would be irretrievably ambiguous and your template would never > be usable. > > 6 (fundamental). Do you know about */dangling references?/* > What do you think happens to your return type when Q is a > reference type? > > So, with the understanding that again your own code fails to > achieve what you say it does, I would think that the closest > C++17 to this would be > > template<class U> > > struct construct { > > template<class QT, class T = std::remove_cvref_t > <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.cppreference.com%2Fw%2Fcpp%2Ftypes%2Fremove_cvref&data=02%7C01%7Cmingxwa%40microsoft.com%7Ce7be00b6b79e40c9c7bd08d746f26b46%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C1%7C637055879330064138&sdata=k3iLdigJE0hlsVtI%2B8zXX2lL%2FNqLLmK6FTbb%2BB0oYP0%3D&reserved=0><QT&&>, > class = std::enable_if_t<std::is_same_v<T, U>>> > > constexpr QT&& operator()(node_proxy&, QT&& po) { > > return T(po); > > } > > }; > > Notice that this is valid C++03 too, if you polyfill > <https://nam06.safelinks.protection.outlook.com/?url=https%3A%2F%2Fen.wikipedia.org%2Fwiki%2FPolyfill_(programming)&data=02%7C01%7Cmingxwa%40microsoft.com%7Ce7be00b6b79e40c9c7bd08d746f26b46%7C72f988bf86f141af91ab2d7cd011db47%7C1%7C1%7C637055879330074130&sdata=n8spgwwuIApiVmlZHd0PVXR%2F88w183kTuuUf0ybrFHA%3D&reserved=0> > the library type-traits — e.g. if you use `typename > std::enable_if<B>::type` in place of `std::enable_if_t<B>`. > > > > > > Thus qualifiers would be: > [...] > > const volatile constexpr > > `constexpr` is not a qualifier. > > –Arthur >
Received on 2019-10-02 00:13:42