[英]Why can't I return a shared pointer in C++14 when the function return type is bool?
I'm using g++ and write a simple function: 我正在使用g ++并编写一个简单的函数:
#include <memory>
std::shared_ptr<char> ptr;
bool fails_compiling()
{
return ptr;
}
From what I can see in the interface, the shared_ptr
implementation includes a bool
operator and I can even apply a quick fix like this: 从我在界面中看到的, shared_ptr
实现包括一个bool
操作符,我甚至可以应用这样的快速修复:
return static_cast<bool>(ptr);
And it now compiles. 它现在编译。
Why would the return algorithm not attempt an auto-conversion to bool
like the if()
and while()
do? 为什么返回算法不像if()
和while()
那样尝试自动转换为bool
?
If you checkout std::shared_ptr
's bool conversion operator, you will see that it's declared as: 如果你签出std::shared_ptr
的bool转换运算符,你会看到它被声明为:
explicit operator bool() const;
The use of explicit
simply tells the compiler to forbid implicit conversion , which is what would have taken place because the return type of your function is different from the object type you are returning. 使用explicit
只是告诉编译器禁止隐式转换 ,这是因为函数的返回类型与返回的对象类型不同而发生的情况。 However, this doesn't affect contextual conversions . 但是,这不会影响上下文转换 。
which occurs in the context of any: 发生在任何情况下:
- controlling expression of
if
,while
,for
; 控制if
,while
,for
表达式;- the logical operators
!
逻辑运算符!
,&&
and||
,&&
和||
; ;- the conditional operator
?:
; 条件运算符?:
;static_assert
;static_assert
;noexcept
.noexcept
。
above quote cited from cppreference 以上引用来自cppreference
Why would the return algorithm not attempt an auto-conversion to
bool
like theif()
andwhile()
do? 为什么返回算法不像if()
和while()
那样尝试自动转换为bool
?
std::shared_ptr::operator bool is explicit
conversion function, so implicit conversion is not allowed, but static_cast
(explicit conversion) works well. std :: shared_ptr :: operator bool是explicit
转换函数,因此不允许隐式转换,但static_cast
(显式转换)效果很好。
When used for if
or while
, contextual conversions takes effect, then the explicit user-defined conversion function will be considered. 当用于if
或while
, 上下文转换生效,则将考虑显式的用户定义转换函数。 In this case, std::shared_ptr
is contextually convertible to bool
. 在这种情况下, std::shared_ptr
可以在上下文中转换为bool
。
In the following five contexts, the type
bool
is expected and the implicit conversion sequence is built if the declarationbool t(e);
在以下五个上下文中,预期类型为bool
,如果声明bool t(e);
则构建隐式转换序列bool t(e);
is well-formed. 结构良好。 that is, the explicit user-defined conversion function such asexplicit T::operator bool() const;
也就是说,显式的用户定义转换函数,如explicit T::operator bool() const;
is considered. 被认为。 Such expression e is said to be contextually convertible to bool . 这种表达e被认为是在语境上可转换为bool 。
- controlling expression of if, while, for; 控制if,while,for的表达式;
- the logical operators !, && and ||; 逻辑运算符!,&&和||;
- the conditional operator ?:; 条件运算符?:;
- static_assert; static_assert;
- noexcept. noexcept。
std::shared_ptr
's conversion-to- bool
operator is declared explicit
and so will generally not be invoked for an implicit conversion. std::shared_ptr
的conversion-to- bool
运算符被声明为explicit
,因此通常不会为隐式转换调用。
In particular it will not be invoked in the context of a return
statement. 特别是它不会在return
语句的上下文中调用。
And it will not be considered for choosing a function overload, ie foo(p)
will not resolve to an overload of foo
that takes a bool
argument. 并且它不会被考虑用于选择函数重载,即foo(p)
将不会解析为带有bool
参数的foo
的重载。
There are however umpteen ways to express the conversion explicitly, including: 然而,有明确表达转换的方法,包括:
!!ptr
ptr != nullptr
ptr.get() != nullptr
static_cast<bool>( ptr )
ptr.operator bool()
bool
. 隐式转换为bool
的一般情况。 There are some cases where explicit
on an operator bool()
is ignored , in order to make things work mainly as in C++03. 在某些情况下, operator bool()
explicit
被忽略 ,以便使事情主要像在C ++ 03中那样工作。 That is, to make things work as with the schemes employed before explicit
was allowed on conversion operators in C++11. 也就是说,在C ++ 11中允许转换运算符允许使用explicit
之前使用的方案。 These exceptions are 这些例外是
use as a (grammar production) condition in an if
, while
or for
, but not in a switch
, 在if
, while
或for
使用(语法生成) 条件 ,但不在switch
,
use as condition in :?
用作以下条件:?
choice, static_assert
or noexcept
, choice, static_assert
或noexcept
,
use as argument to the built-in boolean operators &&
, ||
用作内置布尔运算符&&
, ||
and !
而且!
, or their equivalents and
, or
and not
. 或它们的等同物and
, or
和not
。
Notably, again, these exceptions that allow implicit conversion to bool
in spite of explicit
, known as contextual conversions , do not include a return
statement expression. 值得注意的是,这些异常允许隐式转换为bool
,尽管有explicit
,称为上下文转换 ,但不包括return
语句表达式。
explicit
be ignored also in other cases? 在其他情况下也可以explicit
被忽略吗? In what other cases, if any, can explicit
on a conversion operator be ignored? 在其他情况下,如果有的话,可以忽略转换运算符上的explicit
吗?
Well, none. 好吧,没有。 But a non- explicit
conversion operator, that is, an implicit conversion operator, can be invoked implicitly where the exact type to be converted to is not specified by the context. 但是,可以隐式调用非explicit
转换运算符,即隐式转换运算符,其中上下文未指定要转换为的确切类型。
” Certain language constructs require conversion to a value having one of a specified set of types appropriate to the construct. “某些语言结构需要转换为具有适合于构造的一组指定类型之一的值。 An expression
e
of class typeE
appearing in such a context is said to be contextually implicitly converted to a specified typeT
and is well-formed if and only ife
can be implicitly converted to a typeT
that is determined as follows:E
is searched for conversion functions whose return type is cvT
or reference to cvT
such thatT
is allowed by the context. 出现在这样的上下文中的类类型E
的表达式e
被称为在上下文中隐式地转换为指定类型T
并且当且仅当e
可以被隐式转换为如下确定的类型T
才是良好形式的:E
是搜索返回类型为cvT
或对cvT
引用的转换函数,使得上下文允许T
There shall be exactly one suchT
. 应该只有一个这样的T
For example, 例如,
C++11 §5.3.5/1 (expr.delete): C ++11§5.3.5/ 1(expr.delete):” If of class type, the operand [of
delete
] is contextually implicitly converted (Clause 4) to a pointer to object type. “如果是类类型,则操作数[delete
]在上下文中被隐式转换(第4节)到指向对象类型的指针。
… and so, a bit counter-intuitive to me!, the following should compile with a conforming compiler: ......所以,对我来说有点违反直觉!,以下内容应该使用符合标准的编译器进行编译:
struct Foo { operator int*() const { return nullptr; } }; auto main() -> int { delete Foo(); }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.