• Create Account

## Function that takes unknown amount of strings, how do i vector?

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

15 replies to this topic

### #1BaneTrapper  Members

1493
Like
0Likes
Like

Posted 02 June 2014 - 11:53 AM

Hello.

I have a case as such

void func(std::vector<std::string>> VS);


And i need to call this function with vector that i initialize in the function call.

As such:

func(std::vector<std::string>{std::string("parameter1"), std::string("parameter2")});


Off course this example does not work, but it shows what i require.

The function can take from 1 to X strings passed intro it, and i do not want to pass each string separated, it needs to handle (1,2,3... 66,67...) strings.

What are workarounds? i didn't find one myself.

### #2ApochPiQ  Moderators

21389
Like
0Likes
Like

Posted 02 June 2014 - 12:05 PM

Why exactly do you "need" this to be precisely this way? There are canonical solutions that accomplish the exact same thing but without cramming a bunch of stuff into one function call's parameter list.

Wielder of the Sacred Wands

### #3BaneTrapper  Members

1493
Like
0Likes
Like

Posted 02 June 2014 - 12:29 PM

I have function

void SetForInput(editor::EditorInputType EIT, editor::EditorInputExecuteTypes EIET, std::vector<std::string> & VS);
void SetForInput(editor::EditorInputType EIT, int inputAmount, editor::EditorInputExecuteTypes EIET);


This is what i end up doing

SetForInput(editor::EITIntInt, 2, editor::EIETNewMap);//int int = 2 input
editorInputHints.push_back("Input Map Size X:");//Add as many hints as passed value intro SetForInput, else crash
editorInputHints.push_back("Input Map Size Y:");


Id like to put it all in one function call and make it all simple.

In case i go after a month back and forget to add strings intro editorInputHints, i will have bad time, but if it is in function call its simply gonna note me.

### #4ApochPiQ  Moderators

21389
Like
0Likes
Like

Posted 02 June 2014 - 12:42 PM

Why not just have a function for each type of widget you want to create, with the appropriate number of parameters? You can then use the wrapper function directly, and internally call your other code with the correct data (although I wouldn't keep that interface personally).
Wielder of the Sacred Wands

### #5Consensus  Members

268
Like
4Likes
Like

Posted 02 June 2014 - 12:54 PM

If you just want to pass many strings to function and you are using C++11, the easiest approach is to use initializer list.
void func(std::vector<std::string> const &_vs)
{
for (auto &i : _vs) {
std::cout << i << '\n';
}
}

int main()
{
func({"one", "two", "three"});
return 0;
}

To be honest your first example should work too.

Edit: To make example clearer. There should be constant reference, and to make this example work C++11 is required. http://ideone.com/81wgKw

Edited by Consensus, 02 June 2014 - 01:11 PM.

### #6BaneTrapper  Members

1493
Like
0Likes
Like

Posted 02 June 2014 - 01:02 PM

Why not just have a function for each type of widget you want to create, with the appropriate number of parameters? You can then use the wrapper function directly, and internally call your other code with the correct data (although I wouldn't keep that interface personally).

That is exactly what i am trying to evade.

I got same code for each case... I could have one base function that has 6 lines of code, and all other functions could call it, but it gets to spaghetti code unneedly.

If there is one string passed or 100 string passed, the function is still 6 lines of code. i hate to make allot of functions that take different amount of string parameter and then call the 6 base lines of code, i find it just waste.

Possibly i didn't understand what you meant.

If you just want to pass many strings to function and you are using C++11, the easiest approach is to use initializer list.

void func(std::vector<std::string> const &_vs);

int main()
{
func({"one", "two", "three"});
return 0;
}


void func(std::vector<std::string> const vS)
{
std::cout<<vS[0]<<std::endl;
}

int main()
{

func({"Hello", "Hy"});


compiler error

Ignore that its on 84 line, its the func() call made.

1>c:\c++\projects\test\test\main.cpp(84): error C2143: syntax error : missing ')' before '{'
1>c:\c++\projects\test\test\main.cpp(84): error C2660: 'func' : function does not take 0 arguments
1>c:\c++\projects\test\test\main.cpp(84): error C2143: syntax error : missing ';' before '{'
1>c:\c++\projects\test\test\main.cpp(84): error C2143: syntax error : missing ';' before '}'
1>c:\c++\projects\test\test\main.cpp(84): error C2059: syntax error : ')'



Possible i don't have latest c++11?

I have c++11 function as

for(int & i : vecOfInt)
{...}


Edited by BaneTrapper, 02 June 2014 - 01:05 PM.

### #7Cornstalks  Members

7026
Like
4Likes
Like

Posted 02 June 2014 - 01:18 PM

Possible i don't have latest c++11?

I'm guessing you're using Visual Studio. VS <2013 doesn't have initializer lists.
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

### #8BaneTrapper  Members

1493
Like
0Likes
Like

Posted 02 June 2014 - 01:30 PM

Possible i don't have latest c++11?

I'm guessing you're using Visual Studio. VS <2013 doesn't have initializer lists.

I am out dated ...  99$for 2013 upgrade, too broke ATM for that. I will make do with horrible syntax. ### #9Juliean GDNet+ 6202 Like 4Likes Like Posted 02 June 2014 - 01:51 PM I am out dated blink.png... 99$ for 2013 upgrade, too broke ATM for that.

If you don't want to release anything publically in the meanwhile, you can install the November CTP for Visual Studio 2012. It implements almost all of the C++11 features in VS2013, you can later switch onto 2013 with no trouble (it says somewhere that the CTP is for testing purposes only and you should not release any code compiled with it directly).

### #10Consensus  Members

268
Like
0Likes
Like

Posted 02 June 2014 - 02:30 PM

One option is to use something like this:
template <typename T>
struct make_vector
{
make_vector() { }

make_vector(T const &_element)
{
data.push_back(_element);
}

make_vector& operator()(T const &_element)
{
data.push_back(_element);
return *this;
}

operator std::vector<T>()
{
return data;
}

std::vector<T> data;
};

int main()
{
func(make_vector<std::string>("one")("two")("three"));
return 0;
}
It's quite ugly workaround but is also pretty easy to replace it once the initializer list will be available to you.

Edited by Consensus, 02 June 2014 - 02:31 PM.

### #11swiftcoder  Senior Moderators

17816
Like
0Likes
Like

Posted 02 June 2014 - 05:18 PM

One option is to use something like this...
It's quite ugly workaround but is also pretty easy to replace it once the initializer list will be available to you.

Otherwise known as boost::assign::list_of().

Tristam MacDonald - Software Engineer @ Amazon - [swiftcoding] [GitHub]

### #12Aardvajk  Members

12271
Like
0Likes
Like

Posted 03 June 2014 - 03:44 AM

typedef std::vector<std::string> StringList;

StringList &operator<<(StringList &a, const std::string s)
{
a.push_back(s);
return a;
}

void func(const StringList &s);

void f()
{
func(StringList() << "one" << "two" << "three");
}


This sort of thing is used a lot in Qt, although QVector and QList have built-in << operators. The above should work in principle though, but might be better to wrap std::vector<std::string> inside a StringList class.

### #13JohnnyCode  Members

1059
Like
0Likes
Like

Posted 03 June 2014 - 09:47 AM

there is also a rather native solution for strings in a string, by sealing strings upon a common denominator

int vrbcnt=GetVerbs("|go|done|big");

you can proceduraly create the parameter.

Edited by JohnnyCode, 03 June 2014 - 09:49 AM.

### #14Juliean  GDNet+

6202
Like
1Likes
Like

Posted 03 June 2014 - 10:09 AM

there is also a rather native solution for strings in a string, by sealing strings upon a common denominator

Possible, but I wouldn't recommend it, unless there is a parsing solution that I'm unaware of. If you have to parse it manually, its a pain compared to  the vector

void function(const std::vector<std::string>& vStrings)
{
for(auto& str : vStrings)
{
// do stuff
}
}

void function(const std::string& strValues)
{
const auto strCopy = strValues; // we can't modify the incoming string, so copy is necessary, unless we want to store current-position, which makes things even more complicated

auto seperator = strCopy.find("|");
while(seperator != std::string::npos)
{
const auto nextSeperator = strCopy.find("|");
const auto strValue = strCopy.substr(seperator+1, nextSeperator - (seperator + 1));

// do stuff with value

strCopy.erase(seperator);

seperator = strCopy.find("|");
}

if(!strCopy.empty())
{
// do stuff in case eigther there is no seperator or there is still something left - dublicate code incoming!
}
}


I cringe everytime I even have to think about writing something like that... I do believe that there is some logic error in my code though that fixing would require even more code (it is just an example, sue me ;) ).

EDIT: In a less serious manner, this reminds me of Stringly typed (7.), and I personally (seriously again) would not recommend to fall back to parsing values in and out of strings unless you absolutely have to.

Edited by Juliean, 03 June 2014 - 10:15 AM.

### #15Scorpie  Members

256
Like
1Likes
Like

Posted 04 June 2014 - 05:37 AM

Possible i don't have latest c++11?

I'm guessing you're using Visual Studio. VS <2013 doesn't have initializer lists.

I am out dated ...  99$for 2013 upgrade, too broke ATM for that. I will make do with horrible syntax. You can get the Visual Studio 2013 Expess edition for free if it fits your needs. You only have to register your email after 30 days to continue free usage for unlimited period. ### #16BaneTrapper Members 1493 Like 0Likes Like Posted 05 June 2014 - 08:42 AM Possible i don't have latest c++11? I'm guessing you're using Visual Studio. VS <2013 doesn't have initializer lists. I am out dated ... 99$ for 2013 upgrade, too broke ATM for that.

I will make do with horrible syntax.

You can get the Visual Studio 2013 Expess edition for free if it fits your needs. You only have to register your email after 30 days to continue free usage for unlimited period.

thx!

Old topic!

Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.