Objective-C++ 不能在枚举块中使用向量 push_back

Objective-C++ can't use vector push_back within enumerate block

bar.mm

#include <stdlib.h>
#include <string>
#include <vector>

+ (BOOL)addURIs:(NSArray<NSString *>*)URIs {
    std::vector<std::string> uris;
    uris.push_back("1234");    // works!

    [URIs enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        std::string str = std::string([obj UTF8String]);
        uris.push_back(str); // error: No matching member function for call to 'push_back'
    }];
    return YES;
}

我目前正在使用 objective-c++ 将 C++ 库桥接到 Objecitve-C。

我创建了一个包含字符串的向量并尝试 push_back 另一个字符串。

为什么第一个 push_back 成功而第二个 push_back 出现错误?

No matching member function for call to 'push_back'

编辑:

std::vector<std::string> *vector = {};
[URIs enumerateObjectsUsingBlock:^(NSString * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
    std::string str = std::string([obj UTF8String]);
    vector->push_back(str);
}];

使用指针似乎是一种解决方法。

块通过复制构造函数复制它们来捕获局部C++变量,然后它们在块中是const See Reference:

Stack (non-static) variables local to the enclosing lexical scope are captured as const variables.

...

If you use any other C++ stack-based object from within a block, it must have a const copy constructor. The C++ object is then copied using that constructor.

这意味着在块内你只能调用uris向量中标记为const的方法(例如size())。

您可以使用 __block 存储说明符来允许在块内修改变量。

// this will allow it to be modified within capturing blocks
__block std::vector<std::string> uris;

您也可以只用循环而不是块来迭代数组。