【问题标题】:Shared_ptr implementationShared_ptr 实现
【发布时间】:2020-11-19 01:49:58
【问题描述】:

我已经编写了 Shared_ptr 的实现,作为阅读 C++ Primer 书籍的一部分。头文件确实编译正确,但是当我尝试将它与“Blob”类一起使用时,我收到了几个“无匹配函数”错误。

我花了几个小时盯着代码,我认为问题出在构造函数上,但是我仍然是 C++ 初学者,没有任何运气来修复它。我之前在代码审查中发布了这个,但被告知这是“离题”,并被指示在此处发布。那里有关 shared_ptr 实现的其他帖子没有帮助。任何能让我朝着正确方向前进的反馈将不胜感激。

注意:我没有发布 Blob 课程,因为它很长,也没有发布测试课程。如果需要,我很乐意提供。

错误示例:

exercise_16.29.h: In instantiation of 'Blob< <template-parameter-1-1> >::Blob(std::initializer_list<_Tp>) [with T = int]':
exercise_16.30.cpp:9:33:   required from here
exercise_16.29.h:58:103: error: no matching function for call to 'my_shared_ptr<std::vector<int, std::allocator<int> > >::my_shared_ptr(std::shared_ptr<std::vector<int, std::allocator<int> > >)'
 template <typename T> Blob<T>::Blob(std::initializer_list<T> il): data(std::make_shared<std::vector<T>>(il)) { }
                                                                                                       ^
In file included from exercise_16.29.h:10:
exercise_16.28-1.h:50:1: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(const my_shared_ptr< <template-parameter-1-1> >&, void (*)(T*)) [with T = std::vector<int, std::allocator<int> >]'
 my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs, void (*d)(T*)): p(rhs.p), del(d), count(rhs.count) {
 ^~~~~~~~~~~~~~~~
exercise_16.28-1.h:50:1: note:   candidate expects 2 arguments, 1 provided
exercise_16.28-1.h:44:1: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(const my_shared_ptr< <template-parameter-1-1> >&) [with T = std::vector<int, std::allocator<int> >]'
 my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs): p(rhs.p), del(nullptr), count(rhs.count) {
 ^~~~~~~~~~~~~~~~
exercise_16.28-1.h:44:1: note:   no known conversion for argument 1 from 'std::shared_ptr<std::vector<int, std::allocator<int> > >' to 'const my_shared_ptr<std::vector<int, std::allocator<int> > >&'
exercise_16.28-1.h:20:12: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(T*, void (*)(T*)) [with T = std::vector<int, std::allocator<int> >]'
   explicit my_shared_ptr(T *pt, void (*d)(T*)): p(pt), count(new std::size_t(1)), del(d) { } //shared_ptr<T> p(q, d)
            ^~~~~~~~~~~~~
exercise_16.28-1.h:20:12: note:   candidate expects 2 arguments, 1 provided
exercise_16.28-1.h:19:12: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(T*) [with T = std::vector<int, std::allocator<int> >]'
   explicit my_shared_ptr(T *pt): p(pt), count(new std::size_t(1)), del(nullptr) { } // shared_ptr<T> p(q)
            ^~~~~~~~~~~~~
exercise_16.28-1.h:19:12: note:   no known conversion for argument 1 from 'std::shared_ptr<std::vector<int, std::allocator<int> > >' to 'std::vector<int, std::allocator<int> >*'
exercise_16.28-1.h:16:3: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr() [with T = std::vector<int, std::allocator<int> >]'
   my_shared_ptr(): p(nullptr), del(nullptr), count(nullptr) { }
   ^~~~~~~~~~~~~
exercise_16.28-1.h:16:3: note:   candidate expects 0 arguments, 1 provided
exercise_16.28-1.h: In instantiation of 'my_shared_ptr< <template-parameter-1-1> >::~my_shared_ptr() [with T = std::vector<int, std::allocator<int> >]':

Shared_ptr 实现:

#ifndef EXERCISE_16_28_1_H
#define EXERCISE_16_28_1_H

#include <cstddef>
#include <algorithm>

template <typename> class my_shared_ptr;

template <typename T> void swap(my_shared_ptr<T>&, my_shared_ptr<T>&);
template <typename T> my_shared_ptr<T> make_shared(T);

template <typename T> class my_shared_ptr {
    friend void swap<T>(my_shared_ptr<T>&, my_shared_ptr<T>&);
    friend my_shared_ptr make_shared<T>(T);
    public:
        my_shared_ptr(): p(nullptr), del(nullptr), count(nullptr) { }
        //my_shared_ptr(T *pt): p(pt), count(new std::size_t(1)), del(nullptr) { }
        //my_shared_ptr(T *pt, void (*d)(T*)): p(pt), count(new std::size_t(1)), del(d) { }
        explicit my_shared_ptr(T *pt): p(pt), count(new std::size_t(1)), del(nullptr) { } // shared_ptr<T> p(q)
        explicit my_shared_ptr(T *pt, void (*d)(T*)): p(pt), count(new std::size_t(1)), del(d) { } //shared_ptr<T> p(q, d)
        my_shared_ptr(const my_shared_ptr&);        // copy constructor
        my_shared_ptr(const my_shared_ptr&, void (*d)(T*)); // copy constructor with deleter
        my_shared_ptr& operator=(my_shared_ptr&);   // copy assignment operator
        ~my_shared_ptr();               // destructor

        T& operator*() const;
        T* operator->() const;

        T* get();
        my_shared_ptr& swap(my_shared_ptr&); 
        bool unique() const;
        std::size_t use_count() const;
        my_shared_ptr& reset();
        my_shared_ptr& reset(T*);
        my_shared_ptr& reset(T*, void (*d)(T*));
    private:
        T* p;
        void (*del)(T*);
        std::size_t *count;
};

// copy constructor
template <typename T>
my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs): p(rhs.p), del(nullptr), count(rhs.count) { 
    ++*count;
}

// copy constructor with deleter
template <typename T>
my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs, void (*d)(T*)): p(rhs.p), del(d), count(rhs.count) {
    ++*count;
}

// copy assignment operator
template <typename T>
my_shared_ptr<T>& my_shared_ptr<T>::operator=(my_shared_ptr &rhs) {
    ++*rhs.count;
    --*count;   
    if(--*count == 0) {
        del ? del(p) : delete p;
        del ? del(count) : delete count;
    }
    p = rhs.p;
    del = rhs.del;
    return *this;
}

// destructor
template <typename T>
my_shared_ptr<T>::~my_shared_ptr() {
    if(--*count == 0) {
        del ? del(p) : delete p;
        del ? del(count) : delete count;
    }
    del = nullptr;
}

// dereference operator
template <typename T>
T& my_shared_ptr<T>::operator*() const {
    return *p;
}

// member access operator
template <typename T>
T* my_shared_ptr<T>::operator->() const {
    return & this->operator*();
}

// get
template <typename T>
T* my_shared_ptr<T>::get() {
    return p;
}

// member swap
template <typename T>
my_shared_ptr<T>& my_shared_ptr<T>::swap(my_shared_ptr &rhs) {
    using std::swap;
    swap(p, rhs.p);
    swap(del, rhs.del);
    return *this;
}

// unique
template <typename T>
bool my_shared_ptr<T>::unique() const {
    if (*count == 1)
        return true;
    else
        return false;
}

// use_count
template <typename T>
std::size_t my_shared_ptr<T>::use_count() const {
    return count;
}

template <typename T> my_shared_ptr<T>& my_shared_ptr<T>::reset() {
    if (--*count == 0) {
        delete p;
        delete count;
    }
    del = nullptr;
    return *this;
}

template <typename T> my_shared_ptr<T>& my_shared_ptr<T>::reset(T *t) {
    if (--*count == 0) {
        delete p;
        delete count;
    }
    p = t.p;
    del = nullptr;
    return *this;
}

template <typename T> my_shared_ptr<T>& my_shared_ptr<T>::reset(T *t, void (*d)(T*)) {
    if (--*count == 0) {
        delete p;
        delete count;
    }
    p = t.p;
    del = d;
    return *this;
}

// make_shared
template <typename T>
my_shared_ptr<T> make_shared(T t) {
    return my_shared_ptr<T>(new T(t));
}

// non-member swap
template <typename T> inline void swap(my_shared_ptr<T> &lhs, my_shared_ptr<T> &rhs) {
    using std::swap;
    swap(lhs.p, rhs.p);
    swap(lhs.del, rhs.del);
}

#endif

更新

非常感谢到目前为止的有用回复。使用 std::make_shared 而不是 make_shared 是我进行的调试更改,但是我忽略了 std::make_shared 将返回 std::shared_ptr 而不是 my_shared_ptr 的事实。我在下面添加了原始编译器错误消息,其中 Blob 使用了我的 make_shared 实现:

exercise_16.30.cpp:9:33:   required from here
exercise_16.29.h:58:103: error: no matching function for call to 'my_shared_ptr<std::vector<int, std::allocator<int> > >::my_shared_ptr(std::shared_ptr<std::vector<int, std::allocator<int> > >)'
 template <typename T> Blob<T>::Blob(std::initializer_list<T> il): data(make_shared<std::vector<T>>(il)) { }
                                                                                                       ^
In file included from exercise_16.29.h:10:
exercise_16.28-1.h:50:1: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(const my_shared_ptr< <template-parameter-1-1> >&, void (*)(T*)) [with T = std::vector<int, std::allocator<int> >]'
 my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs, void (*d)(T*)): p(rhs.p), del(d), count(rhs.count) {
 ^~~~~~~~~~~~~~~~
exercise_16.28-1.h:50:1: note:   candidate expects 2 arguments, 1 provided
exercise_16.28-1.h:44:1: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(const my_shared_ptr< <template-parameter-1-1> >&) [with T = std::vector<int, std::allocator<int> >]'
 my_shared_ptr<T>::my_shared_ptr(const my_shared_ptr &rhs): p(rhs.p), del(nullptr), count(rhs.count) {
 ^~~~~~~~~~~~~~~~
exercise_16.28-1.h:44:1: note:   no known conversion for argument 1 from 'std::shared_ptr<std::vector<int, std::allocator<int> > >' to 'const my_shared_ptr<std::vector<int, std::allocator<int> > >&'
exercise_16.28-1.h:20:12: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(T*, void (*)(T*)) [with T = std::vector<int, std::allocator<int> >]'
   explicit my_shared_ptr(T *pt, void (*d)(T*)): p(pt), count(new std::size_t(1)), del(d) { } //shared_ptr<T> p(q, d)
            ^~~~~~~~~~~~~
exercise_16.28-1.h:20:12: note:   candidate expects 2 arguments, 1 provided
exercise_16.28-1.h:19:12: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr(T*) [with T = std::vector<int, std::allocator<int> >]'
   explicit my_shared_ptr(T *pt): p(pt), count(new std::size_t(1)), del(nullptr) { } // shared_ptr<T> p(q)
            ^~~~~~~~~~~~~
exercise_16.28-1.h:19:12: note:   no known conversion for argument 1 from 'std::shared_ptr<std::vector<int, std::allocator<int> > >' to 'std::vector<int, std::allocator<int> >*'
exercise_16.28-1.h:16:3: note: candidate: 'my_shared_ptr< <template-parameter-1-1> >::my_shared_ptr() [with T = std::vector<int, std::allocator<int> >]'
   my_shared_ptr(): p(nullptr), del(nullptr), count(nullptr) { }
   ^~~~~~~~~~~~~
exercise_16.28-1.h:16:3: note:   candidate expects 0 arguments, 1 provided
exercise_16.28-1.h: In instantiation of 'my_shared_ptr< <template-parameter-1-1> >::~my_shared_ptr() [with T = std::vector<int, std::allocator<int> >]':```

根据要求,我现在已经包含了 Blob 类和测试代码:

#ifndef BLOB_H
#define BLOB_H

#include <initializer_list>
#include <vector>
#include <string>
#include <memory>
#include <stdexcept>
#include <iostream>
#include "exercise_16.28-1.h"

template <typename> class BlobPtr;
template <typename> class Blob; // needed for parameters in operators below
template <typename T> bool operator==(const Blob<T>&, const Blob<T>&);
template <typename T> bool operator!=(const Blob<T>&, const Blob<T>&);
template <typename T> bool operator<(const Blob<T>&, const Blob<T>&);
template <typename T> bool operator>(const Blob<T>&, const Blob<T>&);
template <typename T> bool operator<=(const Blob<T>&, const Blob<T>&);
template <typename T> bool operator>=(const Blob<T>&, const Blob<T>&);

template <typename T> class Blob {
    friend class BlobPtr<T>;
    friend bool operator==<T>(const Blob<T>&, const Blob<T>&);
    friend bool operator!=<T>(const Blob<T>&, const Blob<T>&);
    friend bool operator< <T>(const Blob<T>&, const Blob<T>&);
    friend bool operator><T>(const Blob<T>&, const Blob<T>&);
    friend bool operator<=<T>(const Blob<T>&, const Blob<T>&);
    friend bool operator>=<T>(const Blob<T>&, const Blob<T>&);
    public:
        typedef T value_type;
        typedef typename std::vector<T>::size_type size_type;
        // constructors
        Blob();
        Blob(std::initializer_list<T> il);
        template <typename It> Blob(It b, It e);
        // members
        size_type size() const { return data->size(); };
        bool empty() const { return data->empty(); }
        // add and remove elements
        void push_back(const T &t) { data->push_back(t); }
        void push_back(T &&t) { data->push_back(std::move(t)); }
        void pop_back();
        // element access
        T& front();
        T& back();
        const T& front() const;
        const T& back() const;
        T& operator[](size_type);
        const T& operator[](size_type) const;
        BlobPtr<T> begin() const;   // return BlobPtr to the first element
        BlobPtr<T> end() const ;    // and one past the last element
    private:
        my_shared_ptr<std::vector<T>> data;
        void check(size_type i, const std::string &msg) const;
};

template <typename T> Blob<T>::Blob(): data(make_shared<std::vector<T>>()) { }
template <typename T> Blob<T>::Blob(std::initializer_list<T> il): data(make_shared<std::vector<T>>(il)) { }

template <typename T> 
template <typename It> Blob<T>::Blob(It b, It e): data(make_shared<std::vector<T>>(b, e)) {}

template <typename T> void Blob<T>::check(size_type i, const std::string &msg) const {
    if (i >= data->size())
        throw std::out_of_range(msg);
}

template <typename T> T& Blob<T>::front() {
    // if the vector is empty, check will throw
    check(0, "front on empty Blob");
    return data->front();
}

template <typename T> const T& Blob<T>::front() const {
    // if the vector is empty, check will throw
    check(0, "front on empty Blob");
    return data->front();
}

template <typename T> T& Blob<T>::back() {
    check(0, "back on empty Blob");
    return data->back();
}

template <typename T> const T& Blob<T>::back() const {
    check(0, "back on empty Blob");
    return data->back();
}

template <typename T> T& Blob<T>::operator[](size_type i) {
    return data->at(i);
}

template <typename T> const T& Blob<T>::operator[](size_type i) const {
    return data->at(i);
}

template <typename T> void Blob<T>::pop_back() {
    check(0, "pop_back on empty Blob");
    data->pop_back();
}

template <typename T> bool operator==(const Blob<T> &lhs, const Blob<T> &rhs) {
    return *lhs.data == *rhs.data;
}

template <typename T> bool operator!=(const Blob<T> &lhs, const Blob<T> &rhs) {
    return !(lhs == rhs);
}

template <typename T> bool operator<(const Blob<T> &lhs, const Blob<T> &rhs) {
    return *lhs.data < *rhs.data;
}

template <typename T> bool operator>(const Blob<T> &lhs, const Blob<T> &rhs) {
    return rhs < lhs;
}

template <typename T> bool operator<=(const Blob<T> &lhs, const Blob<T> &rhs) {
    return !(lhs > rhs);
}

template <typename T> bool operator>=(const Blob<T> &lhs, const Blob<T> &rhs) {
    return !(lhs < rhs);
}

template <typename T> bool operator==(const BlobPtr<T>&, const BlobPtr<T>&);
template <typename T> bool operator!=(const BlobPtr<T>&, const BlobPtr<T>&);
template <typename T> bool operator<(const BlobPtr<T>&, const BlobPtr<T>&);
template <typename T> bool operator>(const BlobPtr<T>&, const BlobPtr<T>&);
template <typename T> bool operator<=(const BlobPtr<T>&, const BlobPtr<T>&);
template <typename T> bool operator>=(const BlobPtr<T>&, const BlobPtr<T>&);

// BlobPtr throws an exception on attempts to access a nonexistent element
template <typename T> class BlobPtr {
    friend bool operator==<T>(const BlobPtr<T>&, const BlobPtr<T>&);
    friend bool operator!=<T>(const BlobPtr<T>&, const BlobPtr<T>&);
    friend bool operator< <T>(const BlobPtr<T>&, const BlobPtr<T>&);
    friend bool operator><T>(const BlobPtr<T>&, const BlobPtr<T>&);
    friend bool operator<=<T>(const BlobPtr<T>&, const BlobPtr<T>&);
    friend bool operator>=<T>(const BlobPtr<T>&, const BlobPtr<T>&);
    public:
        BlobPtr(): curr(0) { }
        BlobPtr(const Blob<T> &a, size_t sz = 0): wptr(a.data), curr(sz) { }
        T& operator*() const { 
            auto p = check(curr, "derefernce past end");
            return (*p)[curr]; // (*p) is the vector to which this object points
        }
        BlobPtr& operator++();  // prefix operators
        BlobPtr& operator--();
        T& deref() const;
        BlobPtr<T>& incr(); // prefix version
    private:
        // check returns a shared_ptr to the vector if the check succeeds
        std::shared_ptr<std::vector<T>>
            check(std::size_t, const std::string&) const;
        // store a weak_ptr, which means the underlying vector might be destroyed
        std::weak_ptr<std::vector<T>> wptr;
        std::size_t curr;   // current position within the vector
};

template <typename T> std::shared_ptr<std::vector<T>>
BlobPtr<T>::check(std::size_t i, const std::string &msg) const {
    auto ret = wptr.lock();     // is the vector still around?
    if (!ret)
        throw std::runtime_error("unbound BlobPtr");
    if (i >= ret->size())
        throw std::out_of_range(msg);
    return ret;         // otherwise, return a shared_ptr to the vector
}

template <typename T> BlobPtr<T>& BlobPtr<T>::operator++() {
    // if curr already points past the end of the container, can't increment it
    check(curr, "increment exceeds bounds");
    ++curr;
    return *this;
}

template <typename T> BlobPtr<T>& BlobPtr<T>::operator--() {
    // if curr is zero, decrementing it will yield an invalid subscript
    --curr; // move the current state back one element
    check(curr, "decrement exceeds bounds");
    return *this;
}

template <typename T> T& BlobPtr<T>::deref() const {
    auto p = check(curr, "dereference past end");
    return (*p)[curr];  // (*p) is the vector to which this object points
}

// prefix: return a reference to the incremented object
template <typename T> BlobPtr<T>& BlobPtr<T>::incr() {
    // if curr already points past the end of the container, can't increment it
    check(curr, "increment past end of BlobPtr");
    ++curr;     // advance the current state
    return *this;
}

template <typename T> bool operator==(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return lhs.deref() == rhs.deref();
}

template <typename T> bool operator!=(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return !(lhs == rhs);
}

template <typename T> bool operator<(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return lhs.deref() < rhs.deref();
}

template <typename T> bool operator>(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return rhs < lhs;
}

template <typename T> bool operator<=(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return !(lhs > rhs);
}

template <typename T> bool operator>=(const BlobPtr<T> &lhs, const BlobPtr<T> &rhs) {
    return !(lhs < rhs);
}


template <typename T> BlobPtr<T> Blob<T>::begin() const {
    return BlobPtr<T>(*this);
}

template <typename T> BlobPtr<T> Blob<T>::end() const {
    return BlobPtr<T>(*this, data->size());
}
#endif

    #include "exercise_16.29.h"
    #include <iostream>
    #include <string>
    #include <vector>
    #include <list>
    
    int main()
    {
        Blob<int> ib{21, 53, 84, 91, 23};
        for (const auto &elem : ib)
            std::cout << elem << ' ';
        std::cout << '\n';
    
        Blob<std::string> sb{"21", "53", "84", "91", "23"};
        for (const auto &elem : sb)
            std::cout << elem << ' ';
        std::cout << '\n';
    
        std::cout << '\n';
        Blob<std::vector<std::string>> vb{ {"21", "5"}, {"53", "23", "42", "23"},
            {"84", "59"}, {"91", "68"}, {"23", "72", "10" } };
        for (const auto &vector : vb) {
            for (const auto &elem : vector)
                std::cout << elem << ' ';
            std::cout << '\n';
        }
    
        int ia[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        std::vector<long> vi = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
        std::list<const char*> w = {"now", "is", "the", "time"};
    
        Blob<int> a1(std::begin(ia), std::end(ia));
        Blob<int> s2(vi.cbegin(), vi.cend());
        Blob<std::string> a3(w.cbegin(), w.cend());
    
        return 0;
    }

【问题讨论】:

  • 错误告诉您没有构造函数可以从std::stared_ptr 转换为my_shared_ptr,而您正试图在Blob 构造函数中执行此操作。我猜你想在那里使用make_shared 而不是std::make_shared
  • make_shared 坏了。不应该是T,而是Args...template&lt;class T, class... Args&gt; my_shared_ptr&lt;T&gt; make_shared(Args&amp;&amp;... args) { return my_shared_ptr&lt;T&gt;(new T(std::forward&lt;Args&gt;(args)...)); }
  • @Evg 没有损坏,它与 std::make_shared 不同,效率也不高,但应该适用于可复制类型。
  • 请显示minimal reproducible example,包括您在哪里使用my_shared_ptr,因为它可能是错误的根源
  • 您是否要同时使用my_shared_ptrstd::shared_ptrdata(std::make_shared&lt;std::vector&lt;T&gt;&gt;(il))我不认为这是你想要做的。

标签: c++ smart-pointers


【解决方案1】:

编译器错误说它调用std::make_shared,它返回std::shared_ptr,您尝试将其传递给my_shared_ptrmy_shared_ptr 没有构造函数采用 std::shared_ptr

一个简单的解决方法是调用make_shared 而不是std::make_shared。更好的解决方法是将make_shared 重命名为my_make_shared,这样ADL 就不会选择std::make_shared 而不是make_shared

【讨论】:

  • 非常感谢您的回复。我对原始帖子添加了更新,以解决混合 std::make_shared 和 my_shared_ptr 的问题。不幸的是,使用我自己的 make_shared 实现仍然会导致错误。
  • @MasterReDWinD 如果您查看错误消息,您应该查看错误消息,它会告诉您它将std::shared_ptr 传递到my_shared_ptr,因为它通过ADL 找到std::make_shared。将您的重命名为 my_make_shared
  • 我已经按照您的建议进行了更改。出于某种原因,仍在调用 std::shared_ptr 构造函数:exercise_16.29.h:58:103: error: no matching function for call to 'my_shared_ptr&lt;std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;::my_shared_ptr(std::shared_ptr&lt;std::vector&lt;int, std::allocator&lt;int&gt; &gt; &gt;)' template &lt;typename T&gt; Blob&lt;T&gt;::Blob(std::initializer_list&lt;T&gt; il): data(my_make_shared&lt;std::vector&lt;T&gt;&gt;(il)) { }
  • my_make_shared 返回什么?
  • 返回类型为my_shared_ptr&lt;T&gt;
猜你喜欢
  • 1970-01-01
  • 2012-06-02
  • 2016-03-20
  • 1970-01-01
  • 2012-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多