【问题标题】:How do I initialise a global map of string to function pointer?如何将字符串的全局映射初始化为函数指针?
【发布时间】:2025-12-04 06:50:01
【问题描述】:
template <typename T>
void draw_rectangle() {
    display();
    glRecti(10, 10, curr_obj_to_draw<T>->get_length() + 10, curr_obj_to_draw<T>->get_breadth() + 10);
}

std::map<std::string, void (*)()> str_to_fp_mapping;

void initialise_map(){
    str_to_fp_mapping = {std::pair<std::string, void (*)()>("rectangle", &draw_rectangle)};
}

错误:

std::pair 没有匹配的构造函数<:string void>

奇怪的是,当它在一个类中时,我能够正确地初始化它,但是以程序的方式把它搞砸了。

如何初始化地图?

【问题讨论】:

  • 尝试str_to_fp_mapping["rectangle"] = &amp;draw_rectangle&lt;type&gt;;str_to_fp_mapping.insert(std::make_pair("rectangle", &amp;draw_rectangle&lt;type&gt;));,其中type是您要传递给模板的类型,例如int等...
  • Remy 在我之前清理了它,但要小心 pre 标签。它们不适用于 C++ 代码。最好将所有代码缩进 4 个空格,以尊重 C++ 代码格式。选择代码并单击{} 按钮或按CTRL+K。
  • @user4581301 今天好多用户都在用&lt;pre&gt;格式化代码,不知道为什么...
  • 您确定不想使用std::function 代替吗?
  • @Remy 不知道。在过去的几周里,我看到了很多这样的反引号。

标签: c++


【解决方案1】:

可以直接使用构造函数初始化:

#include <map>

void draw_rectangle() {
    // ...
}
void draw_circle() {
    // ...
}
void draw_mona_lisa() {
    // .....
}
// templated function
template<class T>
void draw_type() {
    //... 
}

std::map<std::string, void (*)()> str_to_fp_mapping {
    {"draw rectangle", draw_rectangle },
    {"draw circle", draw_circle },
    {"draw mona lisa", draw_mona_lisa },
    {"draw string", draw_type<std::string> } // Template example   
}; 

如果你这样做,那么你永远不必调用initialize 函数,因为它在main 被调用之前被初始化。如果你说:

std::map<std::string, void (*)()> str_to_fp_mapping{}; 

这也初始化了它,但它初始化为一个空映射。

在更复杂的程序中避免双重初始化

如果您的程序被分成几个静态链接的 cpp 文件,您需要避免双重初始化全局变量。有关如何执行此操作的说明,请参阅 this answer

【讨论】:

  • main被调用之前被初始化。非常重要。这意味着如果你做错了,你实际上可以在程序看起来开始运行之前让你的程序崩溃,所以要小心!还要留意静态初始化顺序惨败。
  • 我添加了一个部分地址