我正在使用一个 API,它需要一个包含指针的连续内存块。指针本身可以是nullptr
。
目前,我使用 C 数组:
ID3D11ShaderResourceView* srvs[] = {
room_diffuse_srv.Get(),
lightmap_srv.Get(),
room_normal_srv.Get(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
input.ambient_occlusion,
reflection_srv.Get(),
reflection_extents_srv.Get(),
nullptr,
nullptr,
nullptr
};
ctx->VSSetShaderResources(0, UINT(std::size(srvs)), std::data(srvs));
我的工具链包含 clang-tidy,它建议避免使用 C 数组,std::array
而改用 prefer。
std::array
有一个推论指南,让我可以像这样初始化这样的数组:
std::array srvs = {
room_diffuse_srv.Get(),
lightmap_srv.Get(),
room_normal_srv.Get(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
input.ambient_occlusion,
reflection_srv.Get(),
reflection_extents_srv.Get(),
nullptr,
nullptr,
nullptr
};
这仅当第一个元素和所有后续元素都可以隐式转换为相同(指针)类型时才有效,在本例中为ID3D11ShaderResourceView*
。
一旦第一个元素包含 nullptr,它就会分解:
std::array srvs = {
nullptr,
lightmap_srv.Get(), // error: "a value of type "ID3D11SamplerState *" cannot be used to initialize an entity of type "std::_Enforce_same<std::nullptr_t, std::nullptr_t, ID3D11SamplerState *, std::nullptr_t, std::nullptr_t, ID3D11SamplerState *>::type" (aka "std::nullptr_t")"
room_normal_srv.Get(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
nullptr,
input.ambient_occlusion,
reflection_srv.Get(),
reflection_extents_srv.Get(),
nullptr,
nullptr,
nullptr
};
是有意义的,因为第一个元素具有类型std::nullptr_t
。
我可以在不明确指定类型的情况下初始化/推断一个std::array
并允许第一个元素为吗nullptr
?我可以强制转换第一个(nullptr
)元素,但随后我也可以将其写入类型中。