简体   繁体   中英

Convert std::vector<std::string> to const char* const*

I'm working with Vulkan, and I'm trying to pass my validation layer as a vector<string> . But the field ppEnabledLayerNames from VkInstanceCreateInfo only takes const char* const* . I don't understand the type and how to convert my vector's data into it.

std::vector<std::string> v = {
    "VK_LAYER_LUNARG_standard_validation"
};

const char* const* data = std::accumulate(std::next(v.begin()), v.end(),
                                    v[0],
                                    [](std::string a, std::string b) {
                                        return a + b;
                                    }).c_str();

But when I compile, I got this :

error: cannot convert ‘const char*’ to ‘const char* const*’ in assignment
                     }).c_str();

Here's a live example

Here's a way to do it on a std::string :

const std::string str = "test";
const char* str_p = str.c_str();

const char* const* ppEnabledExtensionNames = &str_p;

Be careful if c_str() is part of a temporary string that's getting trashed. You may need to retain a reference to the base string object until you're done with this.

With c_str you will get const char* . A const char* const* is an array of const char* .

  vector<string> vectorOfStrings = {
    "Aa", 
    "Bb", 
    "Cc"
  };

  vector<const char*> vectorOfCStyleStrings(3);

  // convert from string to C style strings
  for (string item : vectorOfStrings)
    vectorOfCStyleStrings.push_back(item.c_str());

  // get vector like a const C style array
  const char* const* arrayOfCStyleStrings = vectorOfCStyleStrings.data();

This is what you're doing in your snippet:

  • concatenate all the strings in v (or crash if v is empty);
  • throw away the resulting string;
  • try to assign a dangling pointer to const char to const char* const* .

The last part did not compile, but that's a good thing - dealing with this in a runtime would be a sad expirience.

By the looks of the interface (namely the ppEnabledLayerNames parameter) one could guess that you don't want to concatenate the strings in the first place, but instead you want to pass an array of c-strings.

Here is how to get it from vector<string> :

vector<const char*> layer_names(v.size());
std::transform(v.begin(), v.end(), layer_names.begin(), [](const string& s)
             { return s.c_str(); });
const char* const* data = layer_names.data(); 

Notice that it will only be valid until either layer_names or v is destroyed.

The better way would be to find a C++-friendly interface for Vulkan, I can't help with that though.

I finally found the solution this morning, using std::accumulate

auto d = std::accumulate(
    std::next(v.begin()), v.end(),
    v[0],
    [](std::string a, std::string b) {
        return a + b;
    }).c_str();

const char* const* data = &d;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM