首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >“上下文转换”与‘&&’和‘{#}’操作符如何与用户定义的操作符重载协同工作?

“上下文转换”与‘&&’和‘{#}’操作符如何与用户定义的操作符重载协同工作?
EN

Stack Overflow用户
提问于 2011-09-25 01:12:52
回答 1查看 654关注 0票数 4

从@Xeo的优秀c++-faq问题:Is the safe-bool idiom obsolete in C++11?我了解到不再需要安全bool成语,因为在C++03中需要安全bool的情况下,将自动调用explicit用户定义的对bool的转换。

然而,重载运算符(如&&||! )的能力似乎可以避免这种情况。

除了提供到bool的转换之外,还需要bool的情况很少,operator&&operator||也是如此,但是C++表达式树实现(用于延迟执行和符号数学技术)确实需要覆盖这些实现。

“上下文转换”是在调用用户定义的操作符时发生的吗?要确保operator&&operator||的定义在实现“安全bool”的类型和为“上下文转换”而设计的类型中正确工作,需要使用什么样的SFINAE咒语?

为了澄清,鉴于:

代码语言:javascript
复制
class uses_safe_bool
{
    void f() {};
    typedef void (uses_safe_bool::* safe_bool)();

public:
    operator safe_bool() const { return (rand() & 1)? &uses_safe_bool::f: 0; }
};

class uses_explicit_bool
{
public:
    explicit operator bool() const { return rand() & 1; }
};

template<typename T>
class deferred_expression
{
    // Not convertible to bool
public:
    T evaluate() const;
};

operator||需要哪些签名,以便下列表达式都是有效的:

代码语言:javascript
复制
deferred_expression<bool> db;
uses_safe_bool sb;
uses_explicit_bool eb;
int i;

auto test1 = sb || db;
auto test2 = eb || db;
auto test3 = true || db;
auto test4 = false || db;
auto test5 = i || db;

它们使用的是不同的重载:

代码语言:javascript
复制
auto test6 = db || db;

deferred_expression<int> di;
auto test7 = di || db;

以下内容在编译时被拒绝:

代码语言:javascript
复制
std::string s;
auto test7 = s || db;

std::vector<int> v;
auto test8 = v || db;

deferred_expression<std::string> ds;
auto test9 = ds || db;
EN

回答 1

Stack Overflow用户

发布于 2011-09-25 03:56:46

对于C++03 (安全bool成语)和C++11 (显式转换操作符),规则是一样的:不要为此重载布尔操作符(这样就不会丢失短路行为,加上默认的工作正常)。后者将工作,因为内置布尔运算符的操作数有资格进行上下文转换,例如,对于来自&&的n3290、5.14逻辑和运算符expr.log.and。

1 &&运算符组从左到右.操作数都是上下文转换为bool类型的(第4条)

(强调“地雷”,其他运算符的类似文本)

重载运算符是常规函数调用,因此不进行上下文转换。确保您的重载布尔运算符总是通过过载解析来选择,这样就可以了。例如,这忽视了价值观:

代码语言:javascript
复制
struct evil {
    explicit operator bool() const;
};
void operator||(evil&&, evil&&);

evil e;
// built-in operator||
e || e;

// overloaded operator||
evil() || evil()

注意,当任何一个操作数类型都是类类型时,将通过ADL选择template<typename Lhs, typename Rhs> void operator||(Lhs&&, Rhs&&);,而不考虑cv-限定符和值-类别。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7543001

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档