return 表达式隐式转换为 bool

Implicit conversion of return expressions to bool

在尝试构建一些遗留代码(使用最新版本的 boost)时,我偶然发现了以下问题:

#include <boost/scoped_array.hpp>

bool foo(const boost::scoped_array<int> bar) {
    return bar;
}

bool foo2(const boost::scoped_array<int> bar) {
    const bool r = bar;
    return r;
}

bool foo3(const boost::scoped_array<int> bar) {
    return bar ? true : false;
}

以上源代码无法编译。 foofoo2 都是错误的。确切地说,不允许从 scoped_array 到 bool 的预期隐式转换:

➜  /tmp clang++ --std=c++14 testconversion.cpp -o testconversion.o
testconversion.cpp:4:12: error: no viable conversion from returned value of type 'const boost::scoped_array<int>' to function return type 'bool'
    return bar;
           ^~~
testconversion.cpp:8:16: error: no viable conversion from 'const boost::scoped_array<int>' to 'const bool'
    const bool r = bar;

这提出了两个问题:

  1. 为什么 foo 和 foo2 无效? reference 明确提到:

    when initializing a new object of type T2, including return statement in a function returning T2;

  2. 那是什么时候合法的。遗留代码肯定用于构建 boost 1.48.0。有没有
    1. boost 库的变化
    2. 对 language/compilers
    3. 的更改

查看boost::scoped_array的文档:

operator unspecified-bool-type () const; // never throws

Returns an unspecified value that, when used in boolean contexts, is equivalent to get() != 0.

您必须使用 static_cast 将您的 boost::scoped_array 转换为 bool:

bool foo(const boost::scoped_array<int>& bar) {
    return static_cast<bool>(bar);
}

bool foo2(const boost::scoped_array<int>& bar) {
    const bool r = static_cast<bool>(bar);
    return r;
}

可能只是一个错字,但在您的示例中,您按值传递了 boost::scoped_array。它没有复制构造函数,因此按值传递它也会出错。


它适用于 Boost 1.48.0,因为 operator_bool.hpp was different in that version. In Boost 1.64.0 the same header 包含 explicit operator bool () const;,这会阻止您在编译时从 boost::scoped_array 实例复制初始化 bool它与 -std=c++14(或 -std=c++11)。如果您使用 -std=c++98.

编译代码,您的代码也将适用于 Boost 1.64.0