std::unique_ptr<some_long_and_ugly_name> p;
auto p = std::make_unique<some_long_and_ugly_name>(...);
class C
{
std::unique_ptr<some_long_and_ugly_name> p;
C()
{
p = std::make_unique<some_long_and_ugly_name>(...);
}
};
class C
{
std::optional<some_long_and_ugly_name> p;
C()
{
p.emplace(...); // <-- no template argument duplication here
}
};
class C
{
std::unique_ptr<some_long_and_ugly_name> p;
C()
{
p.new_(...);
}
};
Are the intended semantics similar to reset(), where an existing object is replaced?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to
std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
To view this discussion on the web visit
https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/437f3bb8-6c04-4107-943c-32908b54d82e%40isocpp.org.
How would such a function know how to create a new object for a unique_ptr with a custom deleter?
template<class T, class... Args>
void reallocate_unique(std::unique_ptr<T> &p, Args &&... args)
{
p = std::make_unique<T>(std::forward<Args>(args)...);
}
| From: Victor Dyachenko Sent: Thursday, November 17, 2016 1:51 AM |
To: ISO C++ Standard - Future Proposals |
Reply To: std-pr...@isocpp.org Subject: [std-proposals] Re: emplace-like function for std::unique_ptr |
May be I'm initially wrong and "upgrading" unique_ptr is a bad idea?
My initial task is "late construction" of some members. std::optional is a good solution in most cases, but when member is big and/or seldom used, heap allocation is a better option. I use unique_ptr in such cases but construction suffers from verbosity and, more important, violates DRY principle.
#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
template <typename... Ts>
class make_unique_auto_proxy {
public:
template<typename U>
operator std::unique_ptr<U>() {
return make<U>(std::make_index_sequence<sizeof...(Ts)>());
}
private:
std::tuple<Ts...> ts;
template <typename... Us>
make_unique_auto_proxy(Us&&... us) : ts(std::forward<Ts>(us)...) {
}
template <typename U, size_t... Is>
std::unique_ptr<U> make(std::index_sequence<Is...>) {
return std::make_unique<U>(std::move(std::get<Is>(ts))...);
}
template <typename... Us>
friend make_unique_auto_proxy<Us...> make_unique_auto(Us&&...);
};
template<typename... Ts>
make_unique_auto_proxy<Ts...> make_unique_auto(Ts&&... ts) {
return make_unique_auto_proxy<std::decay_t<Ts>...>(std::forward<Ts>(ts)...);
}
int main() {
auto u = std::make_unique<int>();
u = make_unique_auto(42);
}#include <memory>
#include <tuple>
#include <type_traits>
#include <utility>
template <typename... Ts>
class auto_unique_proxy {
public:
template<typename U>
operator std::unique_ptr<U>() {
return make<U>(std::make_index_sequence<sizeof...(Ts)>());
}
private:
std::tuple<Ts...> ts;
template <typename... Us>
auto_unique_proxy(Us&&... us) : ts(std::forward<Ts>(us)...) {
}
template <typename U, size_t... Is>
std::unique_ptr<U> make(std::index_sequence<Is...>) {
return std::make_unique<U>(std::move(std::get<Is>(ts))...);
}
template <typename... Us>
friend auto_unique_proxy<Us...> auto_unique(Us&&...);
};
template<typename... Ts>
auto_unique_proxy<Ts...> auto_unique(Ts&&... ts) {
return auto_unique_proxy<std::decay_t<Ts>...>(std::forward<Ts>(ts)...);
}
int main() {
using std::make_unique;
auto u = make_unique<int>();
u = auto_unique(42);
}
template<class T, class... Args>
void reallocate_unique(std::unique_ptr<T>& p, Args&&... args)
{
if (p) {
*p = T(std::forward<Args>(args)...);
} else {
p = std::make_unique<T>(std::forward<Args>(args)...);
}
}