Suppose I need to call a function foo
that takes a const std::string
reference from a great number of places in my code:
int foo(const std::string&);
..
foo("bar");
..
foo("baz");
Calling a function with a string literal like this will create temporary std::string
objects, copying the literal each time.
Unless I'm mistaken, compilers won't optimize this by creating a static std::string
object per literal that can be reused for subsequent calls. I know that g++ has advanced string pool mechanisms, but I don't think it extends to the std::string
objects themselves.
I can do this "optimization" myself, which makes the code somewhat less readable:
static std::string bar_string("bar");
foo(bar_string);
..
static std::string baz_string("baz");
foo(baz_string);
Using Callgrind, I can confirm that this does indeed speed up my program.
I thought I'd try to make a macro for this, but I don't know if it's possible. What I would want is something like:
foo(STATIC_STRING("bar"));
..
foo(STATIC_STRING("baz"));
I tried creating a template with the literal as a template parameter, but that proved impossible. And since a function definition in a code block isn't possible, I'm all out of ideas.
Is there an elegant way of doing this, or will I have to resort to the less readable solution?
If that function
foo
does not make a copy of the string then its interface is sub-optimal. It is better to change it to acceptchar const*
orstring_view
, so that the caller is not required to constructstd::string
.Or add overloads:
If you can use boost 1.55 or greater you can do
You could use Boost.Flyweight to make a key-value flyweight from
const char*
tostd::string
. I'm not sure about the details, might be that it is enough to useflyweight<std::string>
everywhere.You may use something like to create your
static std::string
"in place":Live example
This will work for simple strings - w/o whitespace:
Usage in header (parse once!):
In code: