1

我想为 C++ 中的原始类型创建一个包装类,以便我可以为它重载函数和运算符。但是,否则我希望它的行为与原始类型完全一样。例如,我希望它是 POD 类型,因此它可以在由(单独编译的)C 代码访问的结构中使用,并且可以隐式转换为原始类型/从原始类型转换。作为一个具体的例子,我想要像Boost tribool这样的东西,但那是一个保证sizeof为 1 的 POD。C++03 兼容性是非常可取的,但 C++11-only 也可能有用。

像这样开始很容易:

struct tribool_pod {
    unsigned char value; // can be private in C++11
    tribool_pod& operator=(unsigned char v) { value = v; return *this; }
    constexpr operator unsigned char() const { return value; }
    tribool_pod& operator=(bool v) { value = v ? 1 : 0; return *this; }
    constexpr operator bool() const { return value == 1; }
};

请注意,没有用户定义的构造函数,因此到目前为止它是一个 POD 类型。但是,我在编写运算符时遇到了第一个障碍:

constexpr tribool_pod operator!() const {
    return value == 0 ? <true-value> :
           value == 1 ? <false-value> :
           <indeterminate-value>;
}

在这种情况下,在表达式中创建实例的最佳方法是什么<true-value>?在 C++11 中,我可以使用tribool_pod{true},但是在 C++03 中有什么方法吗?如果 C++03 中的结构只能在变量声明中初始化,那么我能想到的为之类的东西编写常量表达式的唯一方法<true-value>是引用 a static const tribool_pod(它具有外部链接)。这样做的缺点是不是仅标头,并且可能比使用原始类型效率低。

即使在 C++11 中,一个相关的问题是我没有从boolto的转换tribool_pod。显然,如果我添加一个转换构造函数tribool_pod,它就不再是一个 POD。

我是否缺少一些技巧,或者这根本不可能?这似乎是 C++ 构造函数是一个全有或全无命题的不幸结果:构造函数是唯一的隐式转换函数,但如果您定义任何一个,则始终调用一个,并且您不再是 POD 类型。(或者在 C++11 术语中,它具有标准布局,但并非微不足道(可构造))。

或者也许我太担心 POD 了?如果我包含转换构造函数和无操作默认构造函数,我会失去什么?只是超级模糊的事情,比如goto过度初始化?我想我可能可以假设标准布局(例如,在对象的开头没有填充)来自真实世界的编译器的 C++03,即使规范不保证它。

注意:我关心这一点的部分原因是因为我想要从 C 中使用的相同标头(具有降级的功能和安全性)。例如:

#ifdef __cplusplus
struct tribool_pod { unsigned char value; ... };
#else
typedef unsigned char tribool_pod;
#endif
4

1 回答 1

0

使用块静态特殊值的仅标头解决方案:

Foo Foo::f()
{
    static const Foo special = make_special_foo();   // or "= { 1, 2, 3 };" etc.

    return condition ? value : special;
}
于 2013-11-14T21:44:27.960 回答