返回语句中的统一初始化和显式转换操作符为bool

时间:2015-05-27 10:08:45

标签: c++ c++11 c++14

我尝试通过使用统一初始化语法强制在return语句中进行显式转换,如下所示:

#include <iostream>

#include <cstdlib>

struct A
{

    explicit
    operator bool () const
    {
        return false;
    }

};

bool
f()
{
    return {A{}}; // error: no viable conversion from 'void' to 'bool'
    // equivalent to return bool{A{}}; at my mind
}

bool
g()
{
    return static_cast< bool >(A{});
}

struct B
{

    B(A) { ; }

};

B
h()
{
    return {A{}};
    // equivalent to return B{A{}};
}

inline
std::ostream &
operator << (std::ostream & _out, B const &)
{
    return _out << "B";
}

int
main()
{
    std::cout << std::boolalpha << f() << std::endl;
    std::cout << std::boolalpha << g() << std::endl;
    std::cout << h() << std::endl;
    return EXIT_SUCCESS;
}

但是有一个错误,因为它指出了相应的代码行注释。

为什么推导出的{A{}}类型为void?一般来说return {/* something */};是什么意思?它与简单初始化期间明显的统一初始化有何不同?

使用的编译器是 clang 3.6.0

1 个答案:

答案 0 :(得分:3)

当您进行用户定义的转换explicit时,您将被迫明确说明您想要的内容。

删除显式,它可以正常工作:

struct A
{
    operator bool () const
    {
        return false;
    }

    operator bool ()
    {
        return true;
    }
};

bool
f()
{
    return A{};   // conversion from A to bool
    return {A{}}; // conversion from braced-init list to bool 
}

编辑:我会尝试解决您的合理问题:

使用bool{A{}};,您应用 direct-list-initialization ,然后返回结果(在一般情况下意味着移动,副本或RVO)。但由于没有从A{}bool的隐式转换,因此失败了。为什么?由于显式转换运算符仅参与直接初始化或显式强制转换,请参阅point(2)here

返回{A{}}的第二种情况类似,但您首先构造init-list,然后将其传递给copy-list-initialize bool返回值。所以问题与bool{A{}};中的问题相同。

编辑:由于涉及void的原因,请参阅@PiotrS的评论。