C++跨文件传匿名命名空间内map给函数时参数为空如何解决
问题根因
你遇到的是C++的**静态初始化顺序惨败(Static Initialization Order Fiasco)**问题:
- 你定义在匿名命名空间的
someMap属于全局静态变量,不同编译单元的全局静态变量初始化顺序没有明确标准,完全由编译器实现决定。 - 你贴出的
funcThatReturnsCorrectMap实现内部遍历了另一个someMap(大概率是其他编译单元定义的全局变量),如果当前编译单元的someMap初始化时机早于被遍历的那个全局someMap,调用函数时被遍历的map还未完成赋值,自然返回空的map,最终你传给函数A的就是空对象。 - 你直接传入初始化列表的场景不需要依赖任何全局变量的初始化顺序,直接构造临时map传入,所以运行正常。
解决方案
方案1:将变量定义移到函数内部(最推荐)
不要在全局作用域定义someMap,把它移到调用函数A的普通函数内部作为局部变量,局部变量的初始化顺序是固定的,调用funcThatReturnsCorrectMap时依赖的全局变量都已经完成初始化:
#include "fileWithfuncA.h" int main() { // 或者其他你调用A的普通函数 std::map<std::string, int> someMap = funcThatReturnsCorrectMap(); A(someMap); // 其他业务逻辑 return 0; }
方案2:用首次使用初始化范式封装全局变量
如果你的someMap需要全局多处使用,可以封装成静态局部变量的返回值,保证初始化时机是第一次被调用时,不会出现顺序问题:
#include "fileWithfuncA.h" namespace { const std::map<std::string, int>& getSomeMap() { static std::map<std::string, int> someMap = funcThatReturnsCorrectMap(); return someMap; } } // 调用A的位置写为 A(getSomeMap());
额外检查项
先确认funcThatReturnsCorrectMap的实现是否存在笔误:如果你函数内部遍历的someMap就是你当前正在初始化的同名变量,属于逻辑错误,初始化过程中遍历还未完成赋值的自身,必然返回空值,需要修改遍历的源变量名为实际的数据源变量,避免重名冲突。
内容的提问来源于stack exchange,提问作者ramtin alami
相关产品推荐
相关产品推荐

