Considering the example at the end of the question, is the map object going to be created every time the function GetName() is called?
Or is the creation going to be optimized away and created as some lookup table?
#include <iostream>
#include <sstream>
#include <map>
#include <string>
#include <boost/assign/list_of.hpp>
enum abc
{
A = 1,
B,
C
};
std::string GetName( const abc v )
{
const std::map< abc, std::string > values =
boost::assign::map_list_of( A, "A" )( B, "B" )( C, "C" );
std::map< abc, std::string >::const_iterator it = values.find( v );
if ( values.end() == it )
{
std::stringstream ss;
ss << "invalid value (" << static_cast< int >( v ) << ")";
return ss.str();
}
return it->second;
}
int main()
{
const abc a = A;
const abc b = B;
const abc c = C;
const abc d = static_cast< abc >( 123 );
std::cout<<"a="<<GetName(a)<<std::endl;
std::cout<<"b="<<GetName(b)<<std::endl;
std::cout<<"c="<<GetName(c)<<std::endl;
std::cout<<"d="<<GetName(d)<<std::endl;
}
Semantically and conceptually and with respect to The Holy Standard, it will be created every time.
The rest is up to your compiler and how you support her:
Possibly the compiler can inline the call and then move deduced invariants outside
to a single point of initialization.
Possibly the compiler dislikes that your
function has external linkage and so does not inline it, then having a hard time
seeing that invariant from other functions.
Possibly the compiler will always check a variables constness and use one-time-initialization
when it can look inside and verify that
boost::assign::map_list_of( A, "A" )( B, "B" )( C, "C" )does not mutate global state.
Many factors, and the only way to be sure is to look at generated code.
In response to a request for quotation:
3.7.2.3 [basic.std.auto]:
This basically means that either it has side effects, in which case it won’t be eliminated, or it hasn’t, in which case it is hardly observable within C++; this means effectively:
The observed behaviour is always as if it is called every time.
In other words: There is no way to guarantee that initialization only happens once with automatic storage, so never assume the opposite.