咨询C++中用compound literal单行初始化Matrix4的标准写法
解决C++中使用复合字面量初始化Matrix4静态成员的标准写法问题
嘿,这个问题我碰到过!你用的C风格复合字面量是GCC等编译器的非标准扩展,所以VS会提示“非标准显式类型转换”。要保留单行初始化的同时符合C++标准,有几个不错的办法:
方法1:使用std::array(C++11及以上)
利用std::array的标准初始化语法,再通过data()方法获取指向内部数组的指针,完全符合标准且单行搞定:
const Matrix4 Matrix4::identity(std::array<float, 16>{1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}.data());
注意:只要你的Matrix4构造函数会拷贝传入指针指向的16个浮点数(而不是单纯保存指针),这个写法就完全安全——临时std::array在构造完成后销毁,但数据已经被拷贝到Matrix4内部了。
方法2:用lambda表达式返回静态数组指针(C++11及以上)
如果担心临时对象的生命周期(虽然静态成员初始化时没问题),可以用lambda创建一个静态constexpr数组,返回其指针:
const Matrix4 Matrix4::identity([]{ static constexpr float identity_arr[16] = {1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}; return identity_arr; }());
这里的static constexpr数组会在程序生命周期内存在,指针不会悬空,而且同样是单行写法。
为什么原来的写法不行?
(float[16]){...}这种C风格复合字面量是C99引入的特性,但C++标准并没有纳入这个语法——它只是部分编译器(比如GCC、Clang)提供的扩展。VS对标准的兼容性更严格,所以会抛出这个警告/错误。
内容的提问来源于stack exchange,提问作者Marin
相关产品推荐
相关产品推荐

