[英]Is it possible to have a static constexpr member with type X of template class X?
I once had 4 classes for 4 different RGB implementations (rgb, rgba, rgbf32, rgbaf32).我曾经有 4 个类用于 4 种不同的 RGB 实现(rgb、rgba、rgbf32、rgbaf32)。 Each class had a member color, and the code worked perfectly fine:每个 class 都有一个成员颜色,并且代码工作得非常好:
struct rgb {
std::uint8_t r;
std::uint8_t g;
std::uint8_t b;
const static rgb red;
};
constexpr rgb rgb::red = rgb{ 255, 0, 0 };
int main() {
constexpr auto red = rgb::red;
}
I had 4 times the code length because of this, so I decided to combine them into one templated class:因此,我的代码长度增加了 4 倍,因此我决定将它们组合成一个模板 class:
#include <cstdint>
#include <type_traits>
#include <array>
template<bool f32, bool alpha>
using rgb_content =
std::conditional_t<(!f32 && !alpha), std::array<std::uint8_t, 3>,
std::conditional_t<(!f32 && alpha), std::array<std::uint8_t, 4>,
std::conditional_t<( f32 && !alpha), std::array<float, 3>,
std::array<float, 4>>>>;
template<bool f32, bool alpha>
struct rgb {
rgb_content<f32, alpha> color;
constexpr static auto get_red() {
return rgb { f32 ? 1 : 255, 0, 0 };
}
const static rgb<f32, alpha> red;
};
template<bool f32, bool alpha>
const rgb<f32, alpha> rgb<f32, alpha>::red = rgb<f32, alpha>::get_red();
int main() {
constexpr auto red = rgb<0, 0>::red;
}
I no longer get the static member red
to work with this template class ( godbolt ):我不再让 static 成员red
与此模板 class (天螺栓)一起工作:
error C2131: expression did not evaluate to a constant
I tried switching around constexpr
and other keywords, but no success.我尝试切换constexpr
和其他关键字,但没有成功。 The only solution I found was naming all possibilities:我找到的唯一解决方案是命名所有可能性:
constexpr rgb<0, 0> rgb<0, 0>::red = rgb<0, 0>::get_red();
constexpr rgb<0, 1> rgb<0, 1>::red = rgb<0, 1>::get_red();
constexpr rgb<1, 0> rgb<1, 0>::red = rgb<1, 0>::get_red();
constexpr rgb<1, 1> rgb<1, 1>::red = rgb<1, 1>::get_red();
int main() {
using u8 = std::uint8_t;
static_assert(rgb<0, 0>::red.color == std::array{(u8)255u, (u8)0u, (u8)0u});
static_assert(rgb<0, 1>::red.color == std::array{(u8)255u, (u8)0u, (u8)0u, (u8)0u});
static_assert(rgb<1, 0>::red.color == std::array{1.0f, 0.0f, 0.0f});
static_assert(rgb<1, 1>::red.color == std::array{1.0f, 0.0f, 0.0f, 0.0f});
}
but this only compiles with MSVC (see here ) and it's pretty unmaintanable.但这只能与 MSVC 一起编译(请参见此处),而且非常难以维护。
Is this even possible to implement?这甚至可以实施吗? Do I have to use constexpr static
member functions like red()
instead?我是否必须使用像red()
这样的constexpr static
成员函数?
constexpr auto red = rgb<0, 0>::red;
rgb<0,0>::red
is not a constexpr
value, this doesn't work. rgb<0,0>::red
不是constexpr
值,这不起作用。
This compiles for me, with gcc 12:这为我编译,gcc 12:
template<bool f32, bool alpha>
struct rgb {
rgb_content<f32, alpha> color;
constexpr static auto get_red() {
return rgb { f32 ? 1 : 255, 0, 0 };
}
constexpr static rgb<f32, alpha> red=get_red();
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.