在朋友中,通过私有析构函数对结构的unique_ptr进行迭代,在VS 2017中失败

问题描述 投票:-1回答:1

这可能是一个简单答案的问题,但我尝试了谷歌搜索结果提供的每个解决方案,但无法在VS 2017中解决这个问题。我有一个带有私有析构函数的结构B。我有另一个结构A,它是struct B的朋友,并试图迭代结构B的唯一指针向量。但我一直收到这个错误:

严重级代码描述项目文件行抑制状态错误C2248'ProjectNamespace :: NwSpec :: ~NwSpec':无法访问类'ProjectNamespace :: NwSpec'中声明的私有成员'TestProject c:\ program files(x86)\ microsoft visual studio \ 2017 \ community \ _vc \ tools \ msvc \ 14.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
        }
c++ visual-studio-2017 stdvector unique-ptr friend
1个回答
1
投票

您需要创建一个负责删除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

© www.soinside.com 2019 - 2024. All rights reserved.