0

I'm new to C++ and I'm trying to pass a collection of a nonvariable amount strings to a function that exists in separate class file in an easy to read manner as such:

//main in Caller.cpp
int main()
{
   string details[] = {"Name","Height","Weight"};

    /* vector<string> detailsV = {"Name","Height","Weight"}; 
     * Would like to use a vector but can't do this because vector cannot be 
     * initialized to = {...} in C++
     */

   Person p = Person();
   p.inspectDetails(details);
}

//Person class in Person.cpp
void inspectDetails(string details [])
{
   int sz = sizeof(details); // this will result in details = "Name" only
}

I've tried:

//Person class in Person.cpp
<template size_t N>
void inspectDetails(string (&details)[N])
{
   int sz = sizeof(details); 
}

However, I don't now how to let the main in the Caller class know about the <template size_t N> which might allow me to use an array of a non-explicit amount. I seem to get an error of "no suitable conversion of std:string[3] to std:string" when trying to call inpectDetails this way.

What is the best way to pass a collection of strings of a non-explicit amount to a function outside of the Caller class whilst maintaining the ability to hardcode the collection's contents like so Collection c = {"...", "...", "..."} in C++? Is there an easier way to pass the full collection of strings to a function with a pointer to a vector or something of that sort?

llllllllll
  • 16,169
  • 4
  • 31
  • 54
Delrog
  • 735
  • 2
  • 11
  • 27
  • What do you mean by "non-explicit amount"? – juanchopanza May 23 '18 at 20:09
  • 9
    `std::vector` can very much be initialized using braces `{ }` - it's called [list initialization](http://en.cppreference.com/w/cpp/language/list_initialization). Are you using a pre-c++11 compiler? – UnholySheep May 23 '18 at 20:10
  • Or a post C++11 compiler that defaults to building to a pre C++11 standard? You may need a `-std=c++0x` or `-std=c++11` command line option to force C++11. – user4581301 May 23 '18 at 20:32
  • How would I determine the version of the compiler that I'm using? – Delrog May 23 '18 at 20:32
  • 1
    @Delrog "How would I determine the version of the compiler" - `compiler-name --version` - for example `g++ --version` usually does the trick ;-) for other compilers different incantations may be needed, but the compiler *documentation* will usually tell you (you *do* read the documentation, don't you?).. – Jesper Juhl May 23 '18 at 21:05
  • Looks like my version lists "MSVC++ 11 _MSC_VER == 1700" meaning the compiler is C++ 11. What defines the compiler that is used? Is it the platform Toolset? What is the Windows SDKs role in all of this? – Delrog May 23 '18 at 22:02

3 Answers3

4

Use a std::vector< std::string > and pass it by reference if you need to change its contents, const reference if you don't need to change them. This is the simplest, most flexible, and clearest way.

Thus:

void inspectDetails( std::vector< std::string > & details );

std::vector< std::string > details = { "Name","Height","Weight" };
inspectDetails( details );

cf. http://en.cppreference.com/w/cpp/container/vector

Rob K
  • 8,757
  • 2
  • 32
  • 36
  • "simplest, most flexible, and clearest" ... can you share _why_? Or _how_? – Drew Dormann May 23 '18 at 20:17
  • 1
    Aside from the trivial code included, why and how are where [a good book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list?lq=1) comes in. – Rob K May 23 '18 at 20:21
  • That's what I initially tried. However, I receive the following intellisense error in VS2012? Error: initialization with '{...}' is not allowed for an object of type "std::vector> – Delrog May 23 '18 at 20:30
  • 2
    Visual Studio 2012 does not fully support c++11. Also Intellisense has false positives. – drescherjm May 23 '18 at 20:32
  • 1
    Upgrade your version of Visual Studio. There's no reason to still be using 2012. – Rob K May 23 '18 at 20:36
0

Passing by const reference is an option. This is what a possible program might look then:

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

void inspectDetails( const std::vector<std::string> & details )
{
    int v = details.size();
    std::cout<<v<<std::endl;
}

int main()
{
    std::vector<std::string> details = {"name", "height", "weight"};

    inspectDetails(details);

    return 0;
}
mahesh
  • 1,028
  • 10
  • 24
  • That's what I initially tried. However, I receive the following intellisense error in VS2012? Error: initialization with '{...}' is not allowed for an object of type "std::vector> – Delrog May 23 '18 at 20:31
  • Intellisense probably has that problem due to older C++ version or VC++ not supporting this initialization format. If the compiler too complains, you need to `push_back(...)` each string. – mahesh May 23 '18 at 20:42
  • @Delrog Intellisense is *not* the compiler. – Jesper Juhl May 23 '18 at 21:10
0

Rob K answered right to you question. I will add that sometimes it's usefull to use std::array rather than a simple array : http://en.cppreference.com/w/cpp/container/array For example, you can easily know the size of your array.

Joseph Garnier
  • 117
  • 1
  • 10