C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Template qualifiers
From: Phil Bouchard (phil_at_[hidden])
Date: 2019-10-04 00:15:56


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
Fornux Logo <http://www.fornux.com>
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] 
> <mailto: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
>


STD-PROPOSALS list run by herb.sutter at gmail.com

Standard Proposals Archives on Google Groups