我遇到了一个非常奇怪的问题,我简化为以下测试用例:#include <iostream>#include <map>#include <string>struct Test{ std::map<std::string, void (Test::*)()> m; Test() { this->m["test1"] = &Test::test1; this->m["test2"] = &Test::test2; } void test1() { } void test2() { } void dispatch(std::string s) { if (this->m.at(s) == &Test::test1) { std::cout << "test1 will be called..." << std::endl; } else if (this->m.at(s) == &Test::test2) { std::cout << "test2 will be called..." << std::endl; } (this->*this->m.at(s))(); }};int main(){ Test t; t.dispatch("test1"); t.dispatch("test2");}它输出 启用优化后,这确实很奇怪。这是怎么回事? 最佳答案 这是Visual C++称为相同COMDAT折叠(ICF)的副产品。它将相同的功能合并到一个实例中。您可以通过在链接器命令行中添加以下开关来禁用它:/OPT:NOICF(从Visual Studio UI中,可以在“属性”->“链接器”->“优化”->“启用COMDAT折叠”下找到)您可以在以下MSDN文章中找到详细信息:/OPT (Optimizations)该开关是链接器阶段的开关,这意味着您将无法仅针对特定模块或特定代码区域(例如可用于编译器阶段优化的__pragma( optimize() ))启用它。但是,一般来说,依靠函数指针或文字字符串指针(const char*)来测试唯一性是不明智的做法。几乎所有C/C++编译器都广泛实现字符串折叠。目前,功能折叠仅在Visual C++上可用,尽管template 元编程的广泛使用增加了对该功能添加到gcc和clang工具链中的要求。编辑:从binutils 2.19开始,附带的金连接器据说还支持ICF,尽管我无法在本地Ubuntu 12.10安装上对其进行验证。关于c++ - 为什么(成员)函数指针在Visual C++中表现得如此怪异?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14176320/