我正在使用g ++编写一个简单的函数:
#include <memory>
std::shared_ptr<char> ptr;
bool fails_compiling()
{
return ptr;
}
从我在界面中看到的内容,shared_ptr
实现包含bool
运算符,我甚至可以应用这样的快速修复:
return static_cast<bool>(ptr);
它现在编译。
为什么返回算法不会像bool
和if()
那样尝试自动转换为while()
?
答案 0 :(得分:6)
如果你签出std::shared_ptr
的bool转换运算符,你会看到它被声明为:
explicit operator bool() const;
使用explicit
只是告诉编译器禁止implicit conversion,这是因为函数的返回类型与返回的对象类型不同而发生的情况。但是,这不会影响contextual conversions。
发生在任何上下文中:
- 控制
的表达if
,while
,for
;- 逻辑运算符
!
,&&
和||
;- 条件运算符
?:
;static_assert
;noexcept
。
以上引用自cppreference
答案 1 :(得分:2)
为什么返回算法不会像
bool
和if()
那样尝试自动转换为while()
?
std::shared_ptr::operator bool是explicit
转换函数,因此不允许隐式转换,但static_cast
(显式转换)效果很好。
当用于if
或while
时,contextual conversions生效,则会考虑显式的用户定义转换函数。在这种情况下,std::shared_ptr
可在上下文中转换为bool
。
在以下五个上下文中,类型
bool
是预期的,如果声明bool t(e);
格式正确,则构建隐式转换序列。也就是说,考虑了显式的用户定义转换函数,例如explicit T::operator bool() const;
。这样的表达式e被认为是在语境上可转换为bool 。
- 控制if,while,for;
的表达式- 逻辑运营商!,&amp;&amp;和||;
- 条件运算符?:;
- static_assert;
- noexcept。
答案 2 :(得分:1)
std::shared_ptr
转换为 - bool
运算符被声明为explicit
,因此通常不会为隐式转换调用。
特别是它不会在return
语句的上下文中调用。
并且不会考虑选择函数重载,即foo(p)
将无法解析为foo
的重载bool
。
然而,有明确表达转换的方法,包括:
!!ptr
ptr != nullptr
ptr.get() != nullptr
static_cast<bool>( ptr )
ptr.operator bool()
bool
。在某些情况下,explicit
上的operator bool()
被忽略,以便使主要工作与C ++ 03一样。也就是说,让事情像C ++ 11中转换运算符允许explicit
之前使用的方案一样工作。这些例外是
在if
,while
或for
中使用(语法制作)条件,但不在switch
中使用,
在:?
选项,static_assert
或noexcept
,
用作内置布尔运算符&&
,||
和!
或其等价物and
,or
和{的参数{1}}。
值得注意的是,这些异常允许隐式转换为not
,而不是bool
,称为上下文转换,但不包含explicit
语句表达
return
吗?在其他情况下(如果有的话),可以忽略转换运算符上的explicit
吗?
嗯,没有。但是,非explicit
转换运算符(即隐式转换运算符)可以隐式调用,而上下文不指定要转换为的确切类型。
“某些语言结构需要转换为具有适当的指定类型集之一的值 到构造。在这样的上下文中出现的类类型
explicit
的表达式e
被称为 上下文隐式转换 到指定的类型E
当且仅当T
可以隐式转换为时,格式良好 类型e
,其确定如下:T
搜索返回类型为 cvE
的转换函数或对 cvT
,以便上下文允许T
。应该只有一个T
。
例如,
C ++11§5.3.5/ 1(expr.delete):“如果是类类型,[{1}}]的操作数是上下文的 隐式转换(第4节)到指向对象类型的指针。
...等等,对我来说有点反直觉!以下应该使用符合标准的编译器进行编译:
T