简体   繁体   中英

List-initializing a vector<string> with 2 char[] pointers

I'm running a C++ 11 program from the command line like so,

marco@host $ ./program.out a bb ccc

The .cpp file used to make the executable looks like this:

#include<iostream>
#include<vector>
#include<string>

int main(int argc, char* argv[]){
  std::vector<std::string> strs = {argv + 1, argv + argc};
  std::cout << strs[2] << endl;
  return 0;
}

When I run it, it outputs ccc . Which I didn't expect since the list initializer contains only two elements of types char*. I've seen list inits like this before:

vector<string> strs = {"str1", "str2", ..., "strN"};

But the pointer init is completely new to me. It seems like the pointers are being treated as begin and end iterators. My question is, how does the compiler know to iterate from argv + 1 to argv + argc to initialize the individual strings in strs ? And just to put things in context, is there a way to use list initialization in a similar way in C to initialize a char* array?

argv is an array of char * . As you know, arrays have this habit of decaying to pointers, if you don't carefully herd them. As such:

{argv + 1, argv + argc}

Both of these expressions result in char ** s.

You are thinking you are just doing an ordinary array/vector initialization here. You're not. It's very misleading, but that's not what's happening. You obviously can't initialize std::string s with char ** s, which would be the case if it were your garden-variety list initialization.

This is actually getting parsed using uniform initialization syntax. Before C++11, this would be equivalent to:

std::vector<std::string> strs(argv + 1, argv + argc);

(for illustrative purposes only, ignoring the most vexing parse issue here).

What you're doing is constructing a vector using its constructor that takes a beginning an an ending iterator of a sequence. std::vector has a bunch of constructors. One of them is a template that takes a beginning and an ending iterator of a sequence and puts the whole thing into the vector. That's what you're doing here.

This really ends up stuffing the vector with your entire argv (except for argv[0]). Which is why you're seeing the results you're seeing.

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