Jump to content

  • Log In with Google      Sign In   
  • Create Account

Banner advertising on our site currently available from just $5!


1. Learn about the promo. 2. Sign up for GDNet+. 3. Set up your advert!


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.

  • You cannot reply to this topic
15 replies to this topic

#1 BaneTrapper   Members   -  Reputation: 1332

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.



Sponsor:

#2 ApochPiQ   Moderators   -  Reputation: 17439

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.



#3 BaneTrapper   Members   -  Reputation: 1332

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.



#4 ApochPiQ   Moderators   -  Reputation: 17439

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

#5 Consensus   Members   -  Reputation: 252

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.


#6 BaneTrapper   Members   -  Reputation: 1332

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

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

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


#7 Cornstalks   Crossbones+   -  Reputation: 6999

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 ]

#8 BaneTrapper   Members   -  Reputation: 1332

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

I will make do with horrible syntax.



#9 Juliean   GDNet+   -  Reputation: 3134

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



#10 Consensus   Members   -  Reputation: 252

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.


#11 swiftcoder   Senior Moderators   -  Reputation: 12897

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]


#12 Aardvajk   Crossbones+   -  Reputation: 8356

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.



#13 JohnnyCode   Members   -  Reputation: 508

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.


#14 Juliean   GDNet+   -  Reputation: 3134

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.


#15 Scorpie   Members   -  Reputation: 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 blink.png...  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.



#16 BaneTrapper   Members   -  Reputation: 1332

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 blink.png...  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.

 

laugh.png 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.



PARTNERS