C++ 重载类型转换到bool和效率

C++ 重载类型转换到bool和效率,c++,performance,operator-overloading,conditional,typecast-operator,C++,Performance,Operator Overloading,Conditional,Typecast Operator,假设我有一个C类,我希望能够隐式转换为bool,以便在if语句中使用 class C { public: ... operator bool() { return data ? true : false; } private: void * data; }; 及 但是cast操作符有一个条件,从技术上讲,这是开销,即使相对来说是微不足道的。如果数据是公共的,我可以用c.data代替,这是完全可能的,并且不涉及任何条件。我怀疑编译器是否会在后一种情况下执行任何涉及条件的隐

假设我有一个C类,我希望能够隐式转换为bool,以便在if语句中使用

class C {
public:
    ...
    operator bool() { return data ? true : false; }
private:
    void * data;
};

但是cast操作符有一个条件,从技术上讲,这是开销,即使相对来说是微不足道的。如果数据是公共的,我可以用c.data代替,这是完全可能的,并且不涉及任何条件。我怀疑编译器是否会在后一种情况下执行任何涉及条件的隐式转换,因为它可能会在零时生成一个跳跃,或者在非零时生成一个跳跃,这实际上不需要任何布尔值,CPU很可能根本不知道这一点

我的问题是typecast操作符重载是否确实比直接使用数据成员效率低

请注意,我确实确定,如果typecast直接返回数据,它也可以工作,可能使用了与if c.data相同的隐式假设类型,并且在实际转换中不会发生

编辑:澄清一下,这件事的要点实际上有点假设性。进退两难的是,布尔本身就是一个假设的构造,它最初在C/C++中并不存在,实际上它只是整数。正如我提到的,typecast可以直接返回数据或使用!=相反,但它确实不是很可读,但即使是这也不是问题所在。我真的不知道如何用它来更好地理解它,C类有一个空洞*,它是一个整数,CPU有使用整数的条件跳跃,问题在于,在中间的假设布尔结构中,有额外的条件。不知道这一澄清是否让事情变得更清楚了

我的问题是typecast操作符重载是否确实比直接使用数据成员效率低

只有检查您的编译器输出(使用您希望使用的特定优化标志)才能确定,然后它可能会在一些看似不相关的更改后发生更改,例如在调用上下文中的某个位置添加一个额外的变量,或者在下一个编译器版本中,等等

更一般地说,如果优化者不倾向于完全处理这种情况,那么C++就不会以速度著称,所以你的几率非常好。
此外,编写工作代码,然后对其进行分析,您将了解到更多关于哪些性能问题实际上是重要的。

这取决于编译器的优化器有多聪明。我认为他们应该足够聪明去清除无用的东西?true:false操作,因为typecast操作应该是内联的

或者你可以写下这个,不用担心:

operator bool() { return data; }
因为从void*到bool有一个内置的隐式类型转换,所以数据在函数外得到类型转换


我不记得if中的条件是bool还是void*;有一点,在C++添加布尔之前,它是后者。操作人员在当时返回void*的iostream类中。

在现代编译器上,这两个函数产生相同的机器代码:

bool toBool1(void* ptr) {
    return ptr ? true : false;
}

bool toBool2(void* ptr) {
    return ptr;
}

所以这真的没什么关系。

你不需要隐式转换为布尔值,显式就足够了。如果数据可用作布尔值,你就不需要使用三元。只需运算符bool{返回数据;}。无论如何,像这样的函数很可能是由编译器内联的,因为它非常简单,因此重载运算符bool和使用c.data可能会产生相同的机器代码。@KarlNicoll数据在技术上可以用作bool,但它不是bool,隐式转换使代码更难阅读。它应该是返回数据!=nullptr;。从什么时候开始重新体验隐式转换的混乱?@JamesKanze-如果你希望显式,那么这样做没有什么错,尽管根据我的经验,你很难找到不知道隐式指针->布尔转换是什么的人。无论如何,对于编译器来说,这种东西很容易优化掉。这不是问题。if,while,for中的条件表达式。。。在上下文中转换为bool,这意味着显式转换。FWIW,bool是在C++98标准之前几年才引入的,而iostream对void*的转换一直持续到C++11,很大程度上是因为这种做法——被称为安全bool习惯用法——避免了隐式转换为bool的一些问题——例如,我注意到即使没有任何优化,输出也是相同的。
bool toBool1(void* ptr) {
    return ptr ? true : false;
}

bool toBool2(void* ptr) {
    return ptr;
}