最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - How can I alias std::make_shared? - Stack Overflow

programmeradmin2浏览0评论

I have a template wrapper ThreadSafeVar for convenient mutex-locking of variables, and I want to alias std::shared_ptr and std::make_shared so I can do e.g. ThreadSafePtr<int> a = ThreadSafePtr_make<int>(2), but I can't figure out how to make ThreadSafePtr_make take arguments.

#include <memory>
#include <mutex>

template<typename T>
class ThreadSafeVar
{
    T value;
    std::mutex mutex{};

public:
    template<typename... Args>
    ThreadSafeVar(Args&&... args) : value{ std::forward<Args>(args)... } {}
    ThreadSafeVar(ThreadSafeVar&) = delete;
    ThreadSafeVar(ThreadSafeVar&&) = delete;
    ThreadSafeVar& operator=(ThreadSafeVar&) = delete;
    ThreadSafeVar& operator=(ThreadSafeVar&&) = delete;

    class Lock
    {
        friend class ThreadSafeVar<T>;
        T& ref;
        std::unique_lock<std::mutex> lock;
        Lock(ThreadSafeVar* tsvar) : ref{ tsvar->value }, lock{ tsvar->mutex } {}
    public:
        T & get() const { return ref; }
    };

    Lock lock() { return Lock{ this }; }
};

template<typename T>
using ThreadSafePtr = std::shared_ptr<ThreadSafeVar<T>>;

template<typename T>
constexpr auto ThreadSafePtr_make = std::make_shared<ThreadSafeVar<T>>;

template <typename T, typename... Args>
constexpr ThreadSafePtr<T>(*ThreadSafePtr_make2)(Args&&...) = &std::make_shared<ThreadSafeVar<T>>;

int main()
{
    ThreadSafePtr<int> a = std::make_shared<ThreadSafeVar<int>>(2);
    a->lock().get()++;
    ThreadSafePtr<int> b = ThreadSafePtr_make<int>();
    ThreadSafePtr<int> c = ThreadSafePtr_make<int>(2); // fail, too many arguments
    ThreadSafePtr<int> d = ThreadSafePtr_make2<int>(2); // fail, too many arguments

    return 0;
}

How do I alias std::make_shared so that it takes arguments?

I have a template wrapper ThreadSafeVar for convenient mutex-locking of variables, and I want to alias std::shared_ptr and std::make_shared so I can do e.g. ThreadSafePtr<int> a = ThreadSafePtr_make<int>(2), but I can't figure out how to make ThreadSafePtr_make take arguments.

#include <memory>
#include <mutex>

template<typename T>
class ThreadSafeVar
{
    T value;
    std::mutex mutex{};

public:
    template<typename... Args>
    ThreadSafeVar(Args&&... args) : value{ std::forward<Args>(args)... } {}
    ThreadSafeVar(ThreadSafeVar&) = delete;
    ThreadSafeVar(ThreadSafeVar&&) = delete;
    ThreadSafeVar& operator=(ThreadSafeVar&) = delete;
    ThreadSafeVar& operator=(ThreadSafeVar&&) = delete;

    class Lock
    {
        friend class ThreadSafeVar<T>;
        T& ref;
        std::unique_lock<std::mutex> lock;
        Lock(ThreadSafeVar* tsvar) : ref{ tsvar->value }, lock{ tsvar->mutex } {}
    public:
        T & get() const { return ref; }
    };

    Lock lock() { return Lock{ this }; }
};

template<typename T>
using ThreadSafePtr = std::shared_ptr<ThreadSafeVar<T>>;

template<typename T>
constexpr auto ThreadSafePtr_make = std::make_shared<ThreadSafeVar<T>>;

template <typename T, typename... Args>
constexpr ThreadSafePtr<T>(*ThreadSafePtr_make2)(Args&&...) = &std::make_shared<ThreadSafeVar<T>>;

int main()
{
    ThreadSafePtr<int> a = std::make_shared<ThreadSafeVar<int>>(2);
    a->lock().get()++;
    ThreadSafePtr<int> b = ThreadSafePtr_make<int>();
    ThreadSafePtr<int> c = ThreadSafePtr_make<int>(2); // fail, too many arguments
    ThreadSafePtr<int> d = ThreadSafePtr_make2<int>(2); // fail, too many arguments

    return 0;
}

How do I alias std::make_shared so that it takes arguments?

Share Improve this question asked Mar 14 at 18:15 H.v.M.H.v.M. 1,7093 gold badges20 silver badges45 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 6

Don't use a function pointer. Use a wrapper function template instead:

template <typename T, typename... Args>
ThreadSafePtr<T> ThreadSafePtr_make(Args&&... args)
{
    return std::make_shared<ThreadSafeVar<T>>(std::forward<Args>(args)...);
}
发布评论

评论列表(0)

  1. 暂无评论