4

假设我有一个vector<string> input,我需要将它传递给一个接受const char**参数的函数。我的想法是使用unique_ptr这样的:

const auto output = make_unique<char*>(size(input));

但我似乎无法将 aconst unique_ptr<const*>变成const char**. 有没有办法做到这一点,或者更简单的选择?

4

3 回答 3

4

我只是建立一个指向c_str()字符串的指针向量,然后得到一个指向它的指针。

std:vector<const char*> pointers;
pointers.reserve(input.size());
for (const auto& e : input)
    pointers.push_back(e.c_str()); // get const char *'s
auto argument = pointers.data(); // get pointer to const char*'s - const char**

或使用unique_ptr

auto pointers = std::make_unique<const char*[]>(size(input))
for (size_t i = 0; i < input.size(); ++i)
    pointers[i]= input[i].c_str(); // get const char *'s
auto argument = pointers.get(); // get pointer to const char*'s - const char**
于 2018-07-16T15:37:59.787 回答
3

我假设你需要这个来适应一些你无法控制的界面,否则我会考虑调整有问题的界面以避免不必要地创建临时数据,只是为了适应一个不合适的界面......

由于您只需要一个已知大小的临时数组,因此最简单的解决方案可能是分配一个指针数组并用指向向量中字符串的指针填充它:

auto pointers = std::make_unique<const char*[]>(size(v));
std::transform(begin(v), end(v), &pointers[0], [](const auto& s) { return s.c_str(); });

该数组也可以放在堆栈上以避免动态内存分配。但是由于您在这里使用字符串并且愿意将数据复制到临时数组中,所以我认为性能并不重要,所以我想没有必要增加复杂性......

于 2018-07-16T15:46:54.070 回答
1

两种方法,取决于 c 接口是否需要空终止:

#include <vector>
#include <string>
#include <algorithm>

auto make_c_interface_null_terminated(std::vector<std::string> const &input) -> std::vector<const char*>
{
    auto result = std::vector<const char*>(input.size() + 1);
    auto to_c_str = [](auto&& str) { return str.c_str(); };
    std::transform(begin(input), end(input), begin(result), to_c_str);
    // implied:  result[result.size() - 1] = nullptr
    return result;
}

auto make_c_interface(std::vector<std::string> const &input) -> std::vector<const char*>
{
    auto result = std::vector<const char*>(input.size());
    auto to_c_str = [](auto&& str) { return str.c_str(); };
    std::transform(begin(input), end(input), begin(result), to_c_str);
    return result;
}


extern "C" void c_interface_requires_null(const char** argv);
extern "C" void c_interface_sized(size_t size, const char** args);


void test(std::vector<std::string> const &input)
{
    auto output1 = make_c_interface_null_terminated(input);
    c_interface_requires_null(output1.data());

    auto output2 = make_c_interface(input);
    c_interface_sized(output1.size(), output1.data());
}
于 2018-07-16T17:32:36.733 回答