将返回表达式隐式转换为bool

时间:2017-06-20 06:40:20

标签: c++ boost implicit-conversion

当尝试构建一些遗留代码(使用最新版本的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明确提到:
      

    初始化T2类型的新对象时,包括返回   返回T2的函数中的语句;

  2. 什么时候合法。遗留代码肯定用于使用boost 1.48.0进行构建。在那里
    1. 升级库中的更改
    2. 对语言/编译器的更改

1 个答案:

答案 0 :(得分:3)

查看boost::scoped_array的文档:

  

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

     

返回未指定的值,当在布尔上下文中使用时,该值等同于get() != 0

您必须使用static_castboost::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在该版本中有所不同。在Boost 1.64.0中,same header包含explicit operator bool () const;,当您使用bool进行编译时,boost::scoped_array阻止您从-std=c++14实例复制初始化-std=c++11(或-std=c++98)。如果您使用#include <string> using namespace std; int main() { string s; // no warning int i; // warning C4101 return 0; } 编译它,您的代码也将与Boost 1.64.0一起使用。