首页 > 解决方案 > 我可以在不使用原始指针的情况下避免在 std::initializer_list 初始化期间进行复制吗?

问题描述

假设我有几个在本地声明的对象,我想使用基于范围的语法进行迭代。这似乎工作得很好,但是,似乎要将本地对象放入 initializer_list 中,需要执行复制。std::shared_ptr这对于像(据我所知)增加引用计数是原子操作的对象来说是个坏消息。我认为可以避免这种情况的唯一方法是使用原始指针。

#include <iostream>
#include <memory>

int main() {
    std::shared_ptr<int> ptrInt1 = std::make_shared<int>(1);
    std::shared_ptr<int> ptrInt2 = std::make_shared<int>(2);
    /* in this loop, ptrInt1 and ptrInt2 are copied before they are binded
       to ptrInt, this is ugly since the reference counter needs to temporarily
       increased */
    for(const std::shared_ptr<int>& ptrInt : {ptrInt1, ptrInt2}) {
        std::cerr << *ptrInt << std::endl;
    }
    /* this solution works, but it feels somewhat ugly having to convert my smart
       pointers to raw pointers to avoid the copying, perhaps there is a better
       solution ?? */
    for(const int* rawPtrInt : {ptrInt1.get(), ptrInt2.get()}) {
        std::cerr << *rawPtrInt << std::endl;
    }
    return 0;
}

有没有办法在不复制它们或诉诸使用原始指针的情况下迭代一组本地声明的对象?

标签: c++shared-ptrinitializer-list

解决方案


您可以使用std::ref来构建std::reference_wrappers 列表。这会隐藏指针并让您编写列表,如

for(const std::shared_ptr<int>& ptrInt : {std::ref(ptrInt1), std::ref(ptrInt2)}) {
    std::cerr << *ptrInt << std::endl;
}

推荐阅读