我想为C ++中的原始类型创建一个包装类,以便为它重载函数和运算符。但是,否则我希望它的行为与原始类型完全相同。例如,我希望它是POD类型,因此它可以用在(单独编译的)C代码访问的结构中,并且可以隐式地转换为原始类型。作为一个具体的例子,我想要类似Boost tribool的东西,但这是一个保证sizeof
为1的POD。C ++ 03兼容性是非常可取的,但是仅C ++ 11可能也是有用的。
像这样的入门很容易:
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>
之类的东西编写常量表达式的唯一方法就是引用static const tribool_pod
(具有外部链接)。这样做的缺点是不能仅使用标头,而且效率可能比使用原始类型低。即使在C ++ 11中,一个相关的问题是我没有从
bool
到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
最佳答案
使用块静态特殊值的仅标头解决方案:
Foo Foo::f()
{
static const Foo special = make_special_foo(); // or "= { 1, 2, 3 };" etc.
return condition ? value : special;
}
关于c++ - 在C++中既可以POD又可以在表达式中构造的原始类型包装器?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/19988908/