使用 std::transform 将 std::vector 容器转换为 std::set

ati*_*tis 2 c++ c++11

更具体地说,我有一些结构的向量

std::vector<SomeStruct> extensions = getThoseExtensions();
Run Code Online (Sandbox Code Playgroud)

wheresomeStructVariable.extensionName返回一个字符串。

我想创建一组extensionName,像这样的std::set<const char*>

使用一些for循环完成后,过程相当简单,但我想改用std::transformfrom <algorithm>


std::transform 有四个参数。

1,2。第一个范围(将第一个范围从和转换为)

3 . 第二个范围/插入器(转换第二个范围)

4 . 一个函数


这是我到目前为止

auto lambdaFn = 
    [](SomeStruct x) -> const char* { return x.extensionName; };

 std::transform(availableExtensions.begin(),
                availableExtensions.end(),
                std::inserter(xs, xs.begin()),
                lambdaFn);
Run Code Online (Sandbox Code Playgroud)

因为std::back_inserterstd::set我使用std::inserter(xs, xs.begin()).


问题是我试图在我的 lambda 函数中返回堆栈内存。那么我该如何解决这个问题呢?

奇怪的是,如果我return从函数中删除它就像我期望的那样工作!但我不明白为什么,这让我害怕未来的影响。


编辑:

我使用的几种结构来代替SomeStructVkExtensionProperties定义在vulkan_core

typedef struct VkExtensionProperties {
    char        extensionName[VK_MAX_EXTENSION_NAME_SIZE];
    uint32_t    specVersion;
} VkExtensionProperties;
Run Code Online (Sandbox Code Playgroud)

Khronos 规格

Ala*_*les 7

您可能无法创建一组 of ,char *除非extensionName具有相同值的所有实例都指向相同的 char 数组(它将存储唯一指针而不是唯一值)。如果您std::set<std::string>改为使用,这将既有效又仅存储唯一值并解决您的可变生命周期问题,因为std::string它会在必要时为您复制(或移动)自身:

auto lambdaFn = 
    [](const SomeStruct& x) { return std::string(x.extensionName); };
std::set<std::string> xs;
std::transform(availableExtensions.begin(),
                availableExtensions.end(),
                std::inserter(xs, xs.begin()),
                lambdaFn);
Run Code Online (Sandbox Code Playgroud)