C++ Logo

std-proposals

Advanced search

Re: Template qualifiers

From: Phil Bouchard <phil_at_[hidden]>
Date: Fri, 4 Oct 2019 02:37:01 -0400
Please disregard #1, but #2 is still applicable.

-- 
Phil Bouchard
Founder
C.: (819) 328-4743
> On Oct 4, 2019, at 1:15 AM, Phil Bouchard <phil_at_[hidden]> wrote:
> 
> 1. a) Here's a real-life example of a generic constructor that simply gets rid if a "node_proxy", depending of the type of object:
> 
> template <typename T, bool = has_static_member_function___proxy<T, T const & (node_proxy &, T const &)>::value>
>     struct construct
>     {
>         template <typename... Args>
>             inline T operator () (node_proxy & __y, char const * n, Args &&... args) const
>             {
>                 return T(std::forward<Args>(args)...);
>             }
>     };
> 
> template <typename T>
>     struct construct<T, true>
>     {
>         template <typename... Args>
>             inline T operator () (node_proxy & __y, char const * n, Args &&... args) const
>             {
>                 return T(__y, std::forward<Args>(args)...);
>             }
> 
>         [...]
>     };
> 
> 
> 
> Taken from:
> 
> https://github.com/philippeb8/fcxxss/blob/master/root_ptr/include/boost/smart_ptr/root_ptr.hpp#L1187
> 
> 
> 
> And called like this:
> 
> struct LocalType
> 
> {
> 
>     node_proxy & __x;
> 
>     constexpr LocalType(node_proxy & __x) : __x(__x) {}
> 
>     static LocalType const & proxy(node_proxy &, LocalType const &) {} // has_static_member_function___proxy<...>::value will be true
> 
> };
> 
> node_proxy __x;
> 
> LocalType t = construct<LocalType>()(__x);
> 
> 
> 
> 1. b) The problem is the last expression will lose its "constexpr" property, making its purpose not very useful. And there is no way to overload "construct<T, bool>::operator ()" based on the "constexpr" property, unless it becomes a qualifier.
> 
> 
> 
> 2. a) Like I was saying before, the need for the "const" overloads on the "this" parameter forces us to create redundant code and disregards the "volatile" qualifier:
> 
> https://gcc.gnu.org/onlinedocs/libstdc++/latest-doxygen/a06712.html
> 
> 
> 
> 2. b) The only solution I can foresee is to add a new "qualifier" template token type:
> 
> template <qualifier Q>
> 
>     iterator     end () Q noexcept;
>  
> template <qualifier Q>
> 
>     Q T &     front () Q noexcept;
> 
> 
> 
> 2. c) It is also a much cleaner syntax for other use cases:
> 
> 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>>>
>                 constexpr QT&& operator()(node_proxy&, QT&& po) 
> 
>                 {
>                     return T(po);
>                 }
>     };
> 
> We can use instead this much cleaner alternative:
> 
> template<class T>
>     struct construct 
> 
>     {
>         template<qualifier Q>
>                 constexpr Q T&& operator()(node_proxy&, Q T&& po) 
> 
>                 {
>                     return T(po);
>                 }
>     };
> 
> And if "constexpr" becomes a qualifier then simply:
> 
> template<class T>
>     struct construct 
> 
>     {
>         template<qualifier Q>
>                 Q T&& operator()(node_proxy&, Q T&& po) 
> 
>                 {
>                     return T(po);
>                 }
>     };
> 
> 
> 
> Thanks,
> 
> -- 
> 
> Phil Bouchard
> Founder
> C.: (819) 328-4743
> 
> 
> 
> 
> 
>> On 10/3/19 4:07 PM, Arthur O'Dwyer wrote:
>> On Thu, Oct 3, 2019 at 12:26 AM Phil Bouchard <phil_at_[hidden]> wrote:
>>> Verdict?
>>> 
>> 
>> Phil, you should pause and try to come up with a motivating example for the feature you claim to want.
>> Once you have a motivating example, the next step would be to look at what would be the best way to solve it. Maybe there's even a better way than what you originally proposed as a feature!
>> That is, start with a problem, and then propose a solution for the problem. If (by thinking) you end up realizing that you don't have a problem after all, that's actually a good thing.
>> 
>> You do need to slow down and think about your examples. Here's your latest one:
>> 
>>     template <typename T>
>>     struct construct
>>     {
>>         T operator () (node_proxy &, T && t) { return T(t); } // will lose constexpr
>>     };
>> 
>> And here's the perfectly valid C++11 code that solves your stated problem:
>> 
>>     template <typename T>
>>     struct construct
>>     {
>>         constexpr T operator () (node_proxy &, T && t) { return T(t); } // no longer loses constexpr
>>     };
>>  
>> See also: http://sscce.org
>> 
>> –Arthur

Received on 2019-10-04 01:39:14