std::map 表初始化是否优化?
考虑问题末尾的示例,每次调用函数 GetName()
时都会创建地图对象吗?
或者创建的内容是否会被优化并创建为某些查找表?
#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;
}
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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从语义上和概念上以及关于神圣标准而言,它每次都会被创建。
剩下的取决于您的编译器以及您如何支持她:
可能编译器可以内联调用,然后将推导的不变量移到外部
到单点初始化。
可能编译器不喜欢你的
函数具有外部链接,因此不会内联它,然后就很难了
看到与其他函数的不变性。
可能编译器将始终检查变量常量并使用一次性初始化
当它可以查看内部并验证
boost::assign::map_list_of( A, "A" )( B, "B" )( C, "C" )
不会改变全局状态。
因素很多,唯一确定的方法就是查看生成的代码。
响应报价请求:
3.7.2.3 [basic.std.auto]:
这基本上意味着它要么有副作用,在这种情况下它不会被消除,要么没有,在这种情况下它在 C++ 中很难观察到;这意味着有效:
观察到的行为总是就好像它是每次都会调用。
换句话说:没有办法保证自动存储时初始化只发生一次,所以永远不要假设相反的情况。
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.
为什么不使用函子?
Why not use a functor?