Date: Fri, 4 Oct 2019 01:15:56 -0400
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,
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 >
Received on 2019-10-04 00:18:09