在函数范围之外运行C++代码

Ema*_*res 15 c++ static initialization initializer

(我知道)在c ++中,我可以 declare variable超出范围,除了初始化全局/静态变量之外,我不能运行任何代码/语句.


理念

使用下面棘手的代码以便(例如)做一些 std::map操作是一个好主意吗?

在这里,我使用void *fakeVar并初始化它Fake::initializer()并做任何我想要的东西!

std::map<std::string, int> myMap;

class Fake
{
public:
    static void* initializer()
    {
        myMap["test"]=222;
        // Do whatever with your global Variables

        return NULL;
    }
};

// myMap["Error"] = 111;                  => Error
// Fake::initializer();                   => Error
void *fakeVar = Fake::initializer();    //=> OK

void main()
{
    std::cout<<"Map size: " << myMap.size() << std::endl; // Show myMap has initialized correctly :)
}
Run Code Online (Sandbox Code Playgroud)

Som*_*ude 15

解决它的一种方法是让一个带有构造函数的类来执行操作,然后声明该类的虚拟变量.喜欢

struct Initializer
{
    Initializer()
    {
        // Do pre-main initialization here
    }
};

Initializer initializer;
Run Code Online (Sandbox Code Playgroud)

你当然可以有多个这样的类进行杂项初始化.每个翻译单元中的顺序指定为自上而下,但未指定翻译单元之间的顺序.

  • @Emadpres:嗯,这遇到了地图不能是全局的问题,因为当其他文件中的初始化程序运行时它可能不存在. (2认同)
  • 在这种情况下,您可以使用函数将地图声明为静态:map <string,int>&GetMap(){static map <string,int> myMap; 返回myMap; }.调用GetMap的第一个初始化程序将使它成为现实. (2认同)

Sco*_*ham 11

你不需要假类......你可以使用lambda进行初始化

auto myMap = []{
    std::map<int, string> m;
    m["test"] = 222;
    return m;
}();
Run Code Online (Sandbox Code Playgroud)

或者,如果它只是普通数据,则初始化地图:

std::map<std::string, int> myMap { { "test", 222 } };
Run Code Online (Sandbox Code Playgroud)


Pup*_*ppy 6

为了(例如)做一些std :: map操作,使用下面棘手的代码是一个好主意吗?

没有.

任何带有可变非局部变量的解决方案都是一个糟糕的想法.


Ton*_*roy 5

这是不是一个好主意...?

并不是的.如果某人决定在他们的"棘手的初始化"中他们想要使用你的地图,但是在某个系统或其他系统上,或者在特定重新链接之后出于明显的原因,你的地图最终会在他们尝试使用之后被初始化,怎么办?如果你让他们调用一个静态函数来返回对地图的引用,那么它可以在第一次调用时初始化它.使映射成为该函数内的静态局部变量,并在没有此保护的情况下停止任何意外使用.