朋友在 VS 2017 中迭代具有私有析构函数的结构的 unique_ptr 向量失败

Iterating through vector of unique_ptr of a struct with private destructor, by a friend, fails in VS 2017

这可能是一个简单答案的问题,但我尝试了 google 结果提供的所有解决方案,但无法在 VS 中解决此问题 2017.I 有一个结构 B 私有析构函数。我有另一个结构 A,它是结构 B 的朋友,并试图遍历指向结构 B 的唯一指针向量。但我不断收到此错误:

Severity Code Description Project File Line Suppression State Error C2248 'ProjectNamespace::NwSpec::~NwSpec': cannot access private member declared in class 'ProjectNamespace::NwSpec' TestProject c:\program files (x86)\microsoft visual studio17\community\vc\tools\msvc.14.26428\include\memory 2055

任何指点将不胜感激。谢谢。

        struct A
        {
        //functions
        std::vector<std::unique_ptr<NwSpec>> List;
        bool function()const;
        };

        struct NwSpec
        {
            char* Path;//Assume Path is initialized and set with a string.

            private:
                ~NwSpec();

            friend struct A;
        };

        bool A::function()const 
        {
            for (uint32_t i = 0 ; i < List.size(); i++)
            {

            OutputDebugStringA(List[i]->Path);// Error C2248
            }
            // I used iterator to the vector, but getting same error.
            // I used for(const auto& k : List) but getting same access error.
            // NwSpec is visible to A and within ProjectNamespace
        }

您需要创建一个专门的类型来负责删除 NwSpec 对象,并将其提供给 std::unique_ptr:

struct NwSpec;

struct A {
private:
    struct NwSpecDeleter {
        //Note that we're only declaring the function, and not defining it
        void operator()(NwSpec * ptr) const;
    };
public:
    typedef std::unique_ptr<NwSpec, NwSpecDeleter> ptr_type;
    std::vector<ptr_type> List;
    bool function()const;
};

struct NwSpec {
    char* Path;//Assume Path is initialized and set with a string.

private:
    ~NwSpec();

    friend struct A;
};

NwSpec::~NwSpec() {}

void A::NwSpecDeleter::operator()(NwSpec * ptr) const {
    delete ptr;
}

int main() {
    A a;
    a.List.emplace_back(new NwSpec());
    auto ptr = a.List.back().release();
    //This will not compile, as intended
    //delete ptr;
    //Nor will this:
    //ptr->~NwSpec();
    //But this will compile, because the original unique_ptr is perfectly capable of deleting objects:
    a.List.back().reset(ptr);
    a.List.back().reset();//Object is successfully deleted

    a.List.erase(a.List.begin(), a.List.end());
    a.List.emplace_back(new NwSpec());
    //This also compiles
    a.List.erase(a.List.begin(), a.List.end());
    return 0;
}

此代码可以是tested here