Advertisement

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

Started by June 02, 2014 05:53 PM
14 comments, last by BaneTrapper 10 years, 8 months ago

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.

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
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement

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.

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
[Work - ArenaNet] [Epoch Language] [Scribblings]

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


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;
}

I already tried that out


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)
{...}
Advertisement

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

I'm guessing you're using Visual Studio. VS <2013 doesn't have initializer lists.
[size=2][ 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 ]

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 blink.png... 99$ for 2013 upgrade, too broke ATM for that.

I will make do with horrible syntax.


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).

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.

This topic is closed to new replies.

Advertisement