为什么我不能在静态函数中访问私有构造函数,如下所示?

Jim*_* Su 6 c++

我目前正在编写一个弱引用资源管理器,如下所示,编译器抱怨Manager有一个私有构造函数.

我的问题是:为什么我不能在静态函数中访问私有成员函数?

#ifndef TENSOR_MANAGER_H
#define TENSOR_MANAGER_H

#include <memory>
#include <functional>
#include <map>
#include <iostream>

template<typename key_t, typename model_t>
class Manager : public std::enable_shared_from_this<Manager<key_t, model_t> > {
public:
    using self_t = Manager<key_t, model_t>;

public:
    static auto Create() {
        return std::make_shared<self_t>();
    }

public:

    std::shared_ptr<model_t> GetOrAdd(const key_t &&key, const char *data, size_t size) {
        auto pos = m_resources.find(key);
        std::shared_ptr<model_t> tmp;
        if (pos != m_resources.end()) {
            tmp = pos->second.lock();
        }
        if (!tmp) {
            model_t *p = new model_t();

            auto deletor = std::bind(&self_t::releaseItem,
                                     std::weak_ptr<self_t>(this->shared_from_this()),
                                     key,
                                     std::placeholders::_1);

            tmp = std::shared_ptr<model_t>(p, deletor);

            m_resources[key] = std::weak_ptr<model_t>(tmp);
        }
        return tmp;
    }

public:
    void Print() {
        std::cout << "Content: ";
        for (const auto &item : m_resources) {
            std::cout << item.first << " ";
        }
        std::cout << std::endl;
    }

private:
    static void releaseItem(std::weak_ptr<self_t> self, const key_t &key, model_t *p) {
        std::shared_ptr<Manager<key_t, model_t>> mgr = self.lock();
        if (mgr) {
            mgr->m_resources.erase(key);
        }
        delete p;
    }

private:
    std::map<key_t, std::weak_ptr<model_t> > m_resources;

    Manager() = default;
};

#endif //TENSOR_MANAGER_H

Run Code Online (Sandbox Code Playgroud)

现在编译器会给出错误:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1/memory:2043:66: error: field of type 'Manager<std::__1::basic_string<char>, int>' has private default constructor
_LIBCPP_INLINE_VISIBILITY constexpr __compressed_pair_elem() : __value_() {}
Run Code Online (Sandbox Code Playgroud)

use*_*670 11

因为它是std::make_shared调用私有构造函数的库函数.


P.W*_*P.W 10

根据Cppreference,注释make_shared清楚地说明:

std::shared_ptr<T>(new T(args...))T如果在可访问的上下文中执行,则可以调用非公共构造函数,同时std::make_shared需要公共访问所选构造函数.

由于在这种情况下选择的构造函数是private,编译失败.
如果您仍然希望保持private用表格std::shared_ptr<T>(new T(args...))static功能Create.

编辑:
如果你打算使用make_shared它也是一个private构造函数,你可以使用这个使用空嵌套classexplicit构造函数的hack .

一个最小的例子.

#include <memory>

class Bar : public std::enable_shared_from_this<Bar> 
{

private:
    class Foo {};
    Bar() = default;

public:
    static auto Create() {        
        return std::make_shared<Bar>(Foo());
    }  
    explicit Bar(Foo);    
};

int main()
{
    auto i = Bar::Create();
}
Run Code Online (Sandbox Code Playgroud)

DEMO.

您可以根据您的要求调整以上内容.

  • @MM我不这么认为,非常确定`make_shared`会将构造传递给我们不知道的某些分配函数(即使我们知道它也可能不能移植给朋友). (3认同)