Jac*_*ker 5 c++ sizeof static-variables aggregate-initialization
在Win32标准库中,使结构的第一个成员成为结构的大小是一个相当普遍的习惯用法,如下所示:
#include <cstddef>
struct wrapped_float
{
std::size_t value; //Initialize with sizeof(wrapped_float)
float other; //Actual info
};
Run Code Online (Sandbox Code Playgroud)
如果我创建一个全局对象,那么有一个简单的初始化语法可以自动适应以下类型的更改a:
constexpr wrapped_float const a{ sizeof(a), 0 }; //OK
Run Code Online (Sandbox Code Playgroud)
我希望我的对象不是结构的静态成员,而不是创建全局对象:
struct test1 {
static constexpr wrapped_float const b{ sizeof(b), 0 }; //Error!
};
Run Code Online (Sandbox Code Playgroud)
但是MSVC在此类代码上出错,抱怨b不是的成员struct test1。因此,我有两个相关的问题:
1.为什么全局成员和静态成员之间有区别?
2.有解决方法吗?
有问题的类型来自Win32标头,因此我无法从中添加或删除成员wrapped_float。(如果有用,我可以使用派生的类/结构。)
的明显变化
struct test2 {
static constexpr wrapped_float const b{ sizeof(test::b), 0 };
};
Run Code Online (Sandbox Code Playgroud)
和
struct test3 {
static constexpr wrapped_float const b{ sizeof(decltype(b)), 0 };
};
Run Code Online (Sandbox Code Playgroud)
产生相同的结果。我已经在Godbolt上进行了验证,该现象也不取决于我是否使用MSVC进行编译,唯一适用于x86-64 Clang的编译器。要得出M(非)WE,请写
int main() {
return a.value + test1::b.value + test2::b.value + test3::b.value;
}
Run Code Online (Sandbox Code Playgroud)
编辑,19年7月26日下午3:10:问题(1)仍未解决。 这个问题表明,constexpr变量不有大小,但这个广场不与事实sizeof(a) 确实编译。
为了后代的缘故,我将总结到目前为止评论中提到的一些解决方法。
保罗·桑德斯(Paul Sanders)指出,如果可以保证类型名称不会更改,则可以编写
struct test4 {
static constexpr wrapped_float const b{ sizeof(wrapped_float), 0 };
};
Run Code Online (Sandbox Code Playgroud)
如果您想减少对的显式引用的数量wrapped_float,那么NRVO可以进行以下工作,
template<typename retval_t, typename...Args>
constexpr retval_t make(Args &&... args)
{
return {sizeof(retval_t), std::forward<Args>(args)...};
}
Run Code Online (Sandbox Code Playgroud)
对应的构造器版本
template<typename obj_ty>
struct auto_size : public obj_ty
{
public:
template<typename...Args>
auto_size(Args &&...args) : obj_ty(sizeof(retval_t), std::forward<Args>...) {}
}
Run Code Online (Sandbox Code Playgroud)
在C ++ 20之前,b / c基类的初始化是通过构造函数进行的,而不是聚合的,才起作用。
| 归档时间: |
|
| 查看次数: |
78 次 |
| 最近记录: |