C++:嵌套 std::conditionals
C++: nested std::conditionals
我有一个简单的图像结构,其中包含实际图像数据。它可以按不同的顺序存储。这是所用结构的简化:
template <typename T, size_t C>
struct Image
{
public:
private:
enum class ColorOrder1
{
UNKNOWN,
INTENSITY
};
enum class ColorOrder3
{
UNKNOWN,
RGB,
BGR
};
enum class ColorOrder4
{
UNKNOWN,
RGBA,
BGRA
};
public:
using ColorOrder =
typename std::conditional<C == 4, ColorOrder4,
std::conditional<C == 3, ColorOrder3, ColorOrder1>>::type;
// ColorOrder colorOrder; // <---- This works fine
ColorOrder colorOrder = ColorOrder::UNKNOWN; // <---- This does not
std::shared_ptr<const std::vector<T>> data;
/* .. and more data. but not imported */
};
我试图根据 std::conditional 的通道数限制可能的颜色顺序。例如。如果我们只有一个通道图像,顺序不应该是 RGBA。这基本上有效。但是,如果我尝试将所有情况下的颜色顺序默认为 UNKNOWN
,它就不会再编译了。尽管 UNKNOWN
存在于所有枚举中。我得到的结果错误是:
error: ‘UNKNOWN’ is not a member of ‘Image<unsigned char, 3>::ColorOrder’ {aka ‘std::conditional<true, Image<unsigned char, 3>::ColorOrder3, Image<unsigned char, 3>::ColorOrder1>’}
ColorOrder colorOrder = ColorOrder::UNKNOWN;
我假设我的嵌套 std::conditional
实际上失败了。如何正确写这个?
提前感谢您的任何反馈。
你错过了 ::type
的内部 std::conditional
using ColorOrder =
typename std::conditional<C == 4,
ColorOrder4,
typename std::conditional<C == 3,
ColorOrder3,
ColorOrder1
>::type
>::type;
或者在 C++14 中,
using ColorOrder =
std::conditional_t<C == 4,
ColorOrder4,
std::conditional_t<C == 3, ColorOrder3, ColorOrder1>>;
.. 啊伙计,问完这个问题我很快就知道出了什么问题:
using ColorOrder = typename std::conditional<
C == 4, ColorOrder4,
typename std::conditional<C == 3, ColorOrder3, ColorOrder1>::type>::type;
请注意我之前错过的附加 typename
和 ::type
。
我会以不同的方式做到这一点:
public:
using PossibleOrders = std::tuple<void, ColorOrder1, void, ColorOrder3, ColorOrder4>;
using ColorOrder = typename std::tuple_element<C, PossibleOrders>::type;
ColorOrder colorOrder = ColorOrder::UNKNOWN;
IMO 这种方法更灵活,也更容易阅读。
顺便说一句,std::shared_ptr<const std::vector<T>>
的使用有点奇怪。可能您想在图像之间共享数据。
我有一个简单的图像结构,其中包含实际图像数据。它可以按不同的顺序存储。这是所用结构的简化:
template <typename T, size_t C>
struct Image
{
public:
private:
enum class ColorOrder1
{
UNKNOWN,
INTENSITY
};
enum class ColorOrder3
{
UNKNOWN,
RGB,
BGR
};
enum class ColorOrder4
{
UNKNOWN,
RGBA,
BGRA
};
public:
using ColorOrder =
typename std::conditional<C == 4, ColorOrder4,
std::conditional<C == 3, ColorOrder3, ColorOrder1>>::type;
// ColorOrder colorOrder; // <---- This works fine
ColorOrder colorOrder = ColorOrder::UNKNOWN; // <---- This does not
std::shared_ptr<const std::vector<T>> data;
/* .. and more data. but not imported */
};
我试图根据 std::conditional 的通道数限制可能的颜色顺序。例如。如果我们只有一个通道图像,顺序不应该是 RGBA。这基本上有效。但是,如果我尝试将所有情况下的颜色顺序默认为 UNKNOWN
,它就不会再编译了。尽管 UNKNOWN
存在于所有枚举中。我得到的结果错误是:
error: ‘UNKNOWN’ is not a member of ‘Image<unsigned char, 3>::ColorOrder’ {aka ‘std::conditional<true, Image<unsigned char, 3>::ColorOrder3, Image<unsigned char, 3>::ColorOrder1>’}
ColorOrder colorOrder = ColorOrder::UNKNOWN;
我假设我的嵌套 std::conditional
实际上失败了。如何正确写这个?
提前感谢您的任何反馈。
你错过了 ::type
的内部 std::conditional
using ColorOrder =
typename std::conditional<C == 4,
ColorOrder4,
typename std::conditional<C == 3,
ColorOrder3,
ColorOrder1
>::type
>::type;
或者在 C++14 中,
using ColorOrder =
std::conditional_t<C == 4,
ColorOrder4,
std::conditional_t<C == 3, ColorOrder3, ColorOrder1>>;
.. 啊伙计,问完这个问题我很快就知道出了什么问题:
using ColorOrder = typename std::conditional<
C == 4, ColorOrder4,
typename std::conditional<C == 3, ColorOrder3, ColorOrder1>::type>::type;
请注意我之前错过的附加 typename
和 ::type
。
我会以不同的方式做到这一点:
public:
using PossibleOrders = std::tuple<void, ColorOrder1, void, ColorOrder3, ColorOrder4>;
using ColorOrder = typename std::tuple_element<C, PossibleOrders>::type;
ColorOrder colorOrder = ColorOrder::UNKNOWN;
IMO 这种方法更灵活,也更容易阅读。
顺便说一句,std::shared_ptr<const std::vector<T>>
的使用有点奇怪。可能您想在图像之间共享数据。