How to properly pass C strings to a lambda inside a variadic template function
<p>Here is my complex situation:</p>

<p>I have a function using variadic template and lambda:</p>

<pre><code>template&lt;typename...Args&gt;
void foo(Args...args) {
    // the arguments are passed to the lambda
    _func = [args...](){ do_sth(args...); };
}
</code></pre>

<p>On observing specific events, the lambda <code>_func</code> would be fired.
My problem is, some of the arguments I passed are C strings, they could be pointing to temporary std string like this:</p>

<pre><code>const char *pStr = __temp_std__string__.c_str();
</code></pre>

<p>Given I call <code>foo(pStr);</code>, and when <code>_func</code> is called, the temporary string that pStr is pointing to, has been released. I would like to know whether there exists a generic way to handle this. I am using C++11.</p>

<p><strong>EDIT:</strong></p>

<p>Perhaps I should post my whole story, as many of you advise to pass std::string instead of C strings, there are reasons that I can't escape from it.</p>

<p>I am developing games using cocos2d-x, which deploys C++11. What I want to do is <strong>to support auto-localisation of labels when players change their preferences of languages</strong> (selected from a UI).</p>

<p>I have saved the text in a couple of files, and each of them contains the localised text of a single language, they are basically under the following structure:</p>

<pre><code>{
    "key1" : "_localized_text1_",
    "key2" : "_localized_text2_",
    ...
}
</code></pre>

<p>The idea is to observe the event on change of language's preference (through a notification), and I would get a key indicating that language from it, so as to fetch the localised text from the proper file. Here is the way how I implement it in the object class <code>Label</code>:</p>

<pre><code>class Label {
    // this method would update the label's displayed text
    void setString(const std::string&amp; text);

    // set a callback for changing language
    void setOnLanguageChangeFunc(std::function&lt;void(Notification*)&gt; func);

    // set a localised text, which would be updated on changing language
    void setLocalizeString(const std::string&amp; key);
};
</code></pre>

<p>the core function is <code>setLocalizeString</code> (I skip the implementations of the other 2 methods as they are intuitive enough from their declaration):</p>

<pre><code>void Label::setLocalizeString(const std::string&amp; key) {
    // the callback lambda
    auto callback = [=](Notification *pNotification){
      setString(LOCALIZED_STRING(key)); 
    }

    // assign the lambda
    setOnLanguageChangeFunc(callback);
}
</code></pre>

<p>where <code>LOCALIZED_STRING</code> is the macro helper of fetching localised string with a key; and the lambda <code>callback</code> would be saved as local member variable of <code>Label</code> in <code>setOnLanguageChangeFunc</code>.</p>

<p>This works great in most cases, what makes the situation complicated is, there are <strong>format specifiers</strong> involved in the localised text, for example:</p>

<pre><code>{
    ...
    "keyN" : "%s eats %d cookies",
    ...
}
</code></pre>

<p>Such format placeholders are passed dynamically in codes:</p>

<pre><code>// formatStr = "Tom eats 5 cookies"
std::string formatStr = StringKit::stringWithFormat("%s eats %d cookies", "Tom", 5);
</code></pre>

<p>where <code>StringKit</code> is a utility to format the string, and it <strong>accepts variadic arguments which would be passed to <code>vsnprintf</code></strong> to yield the output. Now you know why I need to pass C string and not std::string, its just due to the underlying method to format string.</p>

<p>Now I have to modify <code>Label::setLocalizeString</code> so that it could digest the possible variadic arguments:</p>

<pre><code>template&lt;typename... Args&gt;
void setLocalizeString(const std::string&amp; key, Args... args)
{
    // the callback lambda
    auto callback = [=](Notification *pNotification){
         setString(StringKit::stringWithFormat(LOCALIZED_STRING(sKey), args...)); 
    }

    // assign the lambda
    setOnLanguageChangeFunc(callback);
}
</code></pre>

<p>And this is its use case:</p>

<pre><code>// on changing language, the label would display "Tom eats 5 cookies"
pLabel-&gt;setLocalizeString("keyN", "Tom", 5);
</code></pre>

<p>This case would work like a charm as that C string argument is global, but when it is passed from a <strong>temporary std::string</strong>:</p>

<pre><code>std::string tempStr = "Tom";
pLabel-&gt;setLocalizeString("keyN", tempStr.c_str(), 5);
</code></pre>

<p>The C string "Tom" would lose the value on calling the lambda callback, since the pointed std::string, has been gone.</p>

<p>I have tried several ways, like playing with tuple things, or capturing a wrapper class of basic types in the lambda, but none of them could solve the problem. However, I think there should exist some tricky solutions.</p>