简体   繁体   English

C ++使成员对象未命名

[英]C++ make member object unnamed

I want to write convinient Color management class, that would allow me to use different orders of components and basically different setups. 我想编写方便的色彩管理类,该类允许我使用不同顺序的组件和基本上不同的设置。 I want it to be distinguishable at compile-time. 我希望它在编译时能与众不同。 Lets say I have this code: 可以说我有以下代码:

template <typename _valueType>
struct RGBAColorData {
    using ValueType = _valueType;
    union {
        struct { ValueType r, g, b, a; };
        ValueType components[4];
    };
};

This (even if anonymous structs are non-standard) works fine, when I want to use it like this: 当我想像这样使用它时,即使匿名结构是非标准的,它也可以正常工作:

RGBAColorData color;
color.r = whatever;

However, this is not the final form of my code. 但是,这不是我代码的最终形式。 I want it to have "owning" class template, that would in compile-time select between XYZColorData . 我希望它具有“拥有”类模板,该模板将在编译时在XYZColorData之间进行选择。 Lets say it looks like this: 可以这样说:

template <typename _valueType, template <typename> _dataScheme>
struct Color
{
    using ValueType = _valueType;
    using DataScheme = _dataScheme<ValueType>;

    // what now?
    // DataScheme data; // ???
};

This makes a problem, because I want my code to be used like this: 这就造成了一个问题,因为我希望这样使用我的代码:

using RGBAColorF = Color<float, RGBAColorData>;
RGBAColorF brushColor;
brushColor.r = whatever;

This would make a really convinient way to use colors, however I can't think of any solution to this problem. 这将是使用颜色的一种非常方便的方法,但是我想不出任何解决此问题的方法。 Finally, maybe I have wrong approach to this and maybe this can be done with less effort, however I can't think about any other method that wouldn't involve massive amount of template class specializations. 最后,也许我对此有错误的方法,也许可以用更少的精力来完成,但是我无法考虑任何其他不涉及大量模板类专业化的方法。

Don't do it ! 不要做!

Tricking around for obtaining some nice syntactic effects is full of danger and might obliterate future evolution. 兜兜转转以获得一些不错的句法效果充满了危险,并且可能使未来的发展蒙上阴影。

First of all, in C++ only one union member can be active at any moment. 首先,在C ++中,任何时候只有一个工会成员可以处于活动状态。 so switching the use of the array and of the struct is not guaranteed to work, even if on many compilers this may lead to the expected results. 因此,即使在许多编译器上,这也可能会导致预期的结果,因此不能保证切换使用数组和struct不能正常工作。

Then, there is no guarantee for structure members to be contiguous, so that if mixing use of array and struct would work, it might still not lead to a correct result, even if on many compilers this will work as expected. 这样,就不能保证结构成员是连续的,因此,即使将数组和struct混合使用可以工作,即使在许多编译器上都可以按预期工作,也可能无法得出正确的结果。

Or do it with a safer approach... 或者以更安全的方式来做...

If you still like to mix the use of specific color components r, g, b and of the array, you should consider a safer approach: 如果您仍然想混合使用特定的颜色成分r,g,b和阵列中的颜色,则应考虑使用一种更安全的方法:

template <typename _valueType>
struct RGBAColorData {
    using ValueType = _valueType;
    ValueType components[4];
    ValueType &r=components[0], &g=components[1], 
                   &b=components[2], &a=components[3]; // ATTENTION (see explanations)
};

ATTENTION: I made it quick and dirty. 注意:我很快又脏了。 You should better implement the rule of three, with a proper constructor, a copy constructor and an assignment operator, to make sure that the references are not messed up. 您最好使用适当的构造函数,复制构造函数和赋值运算符来实现三个规则,以确保不会弄乱引用。

I do not like this solution so much, but it works safely ( online demo ): the trick is to make r, g, b, a references to specific array items. 我不太喜欢这种解决方案,但是它可以安全运行( 在线演示 ):诀窍是使r,g,b成为对特定数组项的引用。 You are then sure that you can mix the access way, and you are absolutely sure that the mapping between the two is correct. 然后,您可以确保可以混合使用访问方式,并且绝对可以确保两者之间的映射是正确的。

But prefer clean encapsulation 但更喜欢干净的封装

The problem with your initial approach and my workaround is that they oth break the encapsulation: you have to know the inner structure of your color in order to use it. 您最初的方法和我的解决方法的问题是它们会破坏封装:您必须知道颜色的内部结构才能使用它。

With this approach, you'll never able to evolve. 使用这种方法,您将永远无法发展。 For example switching to a CMYK color scheme, or adopting a bit fields encoding would be compromised. 例如,切换到CMYK配色方案或采用位域编码将受到损害。

The proper way would be to have a set of getters and setters to completely hide the inner structure to the outside world. 正确的方法是拥有一组吸气剂和吸气剂,以将内部结构完全隐藏在外部世界中。 Of course, syntactically it does not look so nice, but then you'd really be able to write truly generic color code, where the encoding scheme could be a compile-time strategy. 当然,从语法上看,它看起来不太好,但是您确实可以编写出真正的通用颜色代码,其中编码方案可以作为编译时策略。

Finally, I decided to use inheritance (as Ben Voigt said). 最后,我决定使用继承(如Ben Voigt所说)。 I fixed the other problem, with unions that made code unsafe, using the brilliant method proposed by this answer: 我使用此答案提出的出色方法,解决了另一个使代码不安全的联合的问题:
https://stackoverflow.com/a/494760/4386320 https://stackoverflow.com/a/494760/4386320

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM