Date: Tue, 4 Jun 2024 16:54:52 +0000
No, the constructor does not always have more than one parameter.
And even if it were the case it wouldn't be the case if you scaled the analysis out across the entire ecosystem and every possible user of this new utility.
Trying to force poorly-designed legacy classes to work with this new utility is simply not a compelling reason to vandalize the core language.
I say "poorly-designed" because classes with unary templated constructors are, as I've said before, arguably facially poorly-designed even in a universe where std::elide (or its equivalent) does not exist.
The use cases are anywhere you have one class that wants to wrap another and leave open the possibility of the wrapped class being constructed with maximum genericity. Post-C++17 the most generic way to defer construction to another actor is to allow them to construct the object from the result of a function call (which is exactly what std::elide does). I showed an example of such a class a few emails back, one which has a unary templated constructor which explicitly want to accept std::elide and which wants CTAD to interact with std::elide. I'll paste it here again:
template<typename T>
struct foo {
template<typename... Args>
requires std::constructible_from<T, Args...>
explicit foo(Args&&... args) : t_(std::forward<Args>(args)...) {}
private:
T t_;
};
template<typename T>
explicit foo(T&&) -> foo<deduce_t<T>>;
Where deduce_t was defined in still another email in this chain:
template<typename T>
struct deduce : std::remove_cvref<T> {};
namespace detail::deduce {
template<typename>
struct extract;
template<typename T>
struct extract<elide<T>> : std::type_identity<T> {};
}
template<typename T>
requires requires {
typename detail::deduce::extract<std::remove_cvref_t<T>>::type;
}
struct deduce<T> : std::type_identity<
decltype(std::forward_like<T>(std::declval<
typename detail::deduce::extract<std::remove_cvref_t<T>>::type>())())> {};
template<typename T>
using deduce_t = typename deduce<T>::type;
And then simply write a deduction guide:
template<typename T>
explicit my_class(T&&) -> my_class<deduce_t<T>>;
The class I pasted above can be used, for example, as:
foo f(std::elide([]() { return std::mutex{}; });
In which case it is deduced as foo<std::mutex> and the contained std::mutex is materialized in situ (obviously because std::mutex cannot be copied or moved).
--Robert
________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]rg> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Sent: Tuesday, June 4, 2024 12:44
To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: Re: [std-proposals] std::elide
On Tue, Jun 4, 2024 at 5:31 PM Robert A.H. Leahy wrote:
>
> I explicitly want std::elide or its equivalent to interact with
> CTAD. I explicitly want std::elide to be deduced as a template
> parameter to constructors (unary or otherwise). These are
> both things that I actually do in code I have deployed on
> production systems right now.
Without giving away company secrets, if you can describe the use cases
for that, then we can factor them into the paper?
Quick question: When you want the elider class to be a template
parameter for a constructor, does the constructor always have more
than one parameter?
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
And even if it were the case it wouldn't be the case if you scaled the analysis out across the entire ecosystem and every possible user of this new utility.
Trying to force poorly-designed legacy classes to work with this new utility is simply not a compelling reason to vandalize the core language.
I say "poorly-designed" because classes with unary templated constructors are, as I've said before, arguably facially poorly-designed even in a universe where std::elide (or its equivalent) does not exist.
The use cases are anywhere you have one class that wants to wrap another and leave open the possibility of the wrapped class being constructed with maximum genericity. Post-C++17 the most generic way to defer construction to another actor is to allow them to construct the object from the result of a function call (which is exactly what std::elide does). I showed an example of such a class a few emails back, one which has a unary templated constructor which explicitly want to accept std::elide and which wants CTAD to interact with std::elide. I'll paste it here again:
template<typename T>
struct foo {
template<typename... Args>
requires std::constructible_from<T, Args...>
explicit foo(Args&&... args) : t_(std::forward<Args>(args)...) {}
private:
T t_;
};
template<typename T>
explicit foo(T&&) -> foo<deduce_t<T>>;
Where deduce_t was defined in still another email in this chain:
template<typename T>
struct deduce : std::remove_cvref<T> {};
namespace detail::deduce {
template<typename>
struct extract;
template<typename T>
struct extract<elide<T>> : std::type_identity<T> {};
}
template<typename T>
requires requires {
typename detail::deduce::extract<std::remove_cvref_t<T>>::type;
}
struct deduce<T> : std::type_identity<
decltype(std::forward_like<T>(std::declval<
typename detail::deduce::extract<std::remove_cvref_t<T>>::type>())())> {};
template<typename T>
using deduce_t = typename deduce<T>::type;
And then simply write a deduction guide:
template<typename T>
explicit my_class(T&&) -> my_class<deduce_t<T>>;
The class I pasted above can be used, for example, as:
foo f(std::elide([]() { return std::mutex{}; });
In which case it is deduced as foo<std::mutex> and the contained std::mutex is materialized in situ (obviously because std::mutex cannot be copied or moved).
--Robert
________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]rg> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Sent: Tuesday, June 4, 2024 12:44
To: std-proposals_at_[hidden] <std-proposals_at_[hidden]>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: Re: [std-proposals] std::elide
On Tue, Jun 4, 2024 at 5:31 PM Robert A.H. Leahy wrote:
>
> I explicitly want std::elide or its equivalent to interact with
> CTAD. I explicitly want std::elide to be deduced as a template
> parameter to constructors (unary or otherwise). These are
> both things that I actually do in code I have deployed on
> production systems right now.
Without giving away company secrets, if you can describe the use cases
for that, then we can factor them into the paper?
Quick question: When you want the elider class to be a template
parameter for a constructor, does the constructor always have more
than one parameter?
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
Received on 2024-06-04 16:54:56