explicit关键字在C++中意味着什么?
我在夏天一直使用"Accelerated C++"来学习C++,并且有一个我似乎无法理解的概念.
为什么是
int x;
if (cin >> x){}
Run Code Online (Sandbox Code Playgroud)
相当于
cin >> x;
if (cin){}
Run Code Online (Sandbox Code Playgroud)
通过查看代码,在我看来,我们使用cin作为变量.但是,我认为这是一个功能.为什么我们可以以这种方式使用cin,因为它是x,它具有我们输入键盘的任何值?
如果以下测试程序
#include <iostream>
class A {
public:
A() {}
explicit operator bool() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return true;
}
// explicit operator bool() {
// std::cout << __PRETTY_FUNCTION__ << std::endl;
// return true;
// }
const operator int() const {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return 1;
}
operator int() {
std::cout << __PRETTY_FUNCTION__ << std::endl;
return 1;
}
};
int main() {
A a;
if (a) {
std::cout << "bool()" << std::endl;
}
if (a + …Run Code Online (Sandbox Code Playgroud) 我最近在学习C++,我注意到了一个关于cppreference的例子,其中一部分是这样的:
struct B
{
explicit B(int) { }
explicit operator bool() const { return true; }
};
int main()
{
B b2(2); // OK: direct-initialization selects B::B(int)
if (b2) ; // OK: B::operator bool()
}
Run Code Online (Sandbox Code Playgroud)
隐式转换的介绍告诉我"当表达式在if语句或循环中使用时",此表达式(b2)的结果将被bool隐式转换为类型.
此外,显式说明符的介绍告诉我"转换函数是否显式,它不能用于隐式转换".
由于b2将被隐式if(b2)转换,并且转换函数是explicit,怎么回事if(b2)?
#include <iostream>
using namespace std;
struct A
{
explicit operator bool() const
{
return true;
}
operator int()
{
return 0;
}
};
int main()
{
if (A())
{
cout << "true" << endl;
}
else
{
cout << "false" << endl;
}
}
Run Code Online (Sandbox Code Playgroud)
我的期望是A()将在上下文中转换为bool使用my operator bool(),因此打印true.
但是,输出false显示已operator int()被调用.
为什么我explicit operator bool没有按预期召唤?
在C++ Primer 第 5 版中。, 第 14 章讨论转换运算符:
在该标准的早期版本中,想要定义到 bool 的转换的类面临一个问题:因为 bool 是一种算术类型,转换为 bool 的类类型对象可以在任何需要算术类型的上下文中使用。
这种转换可能以令人惊讶的方式发生。特别是,如果 istream 转换为 bool,则以下代码将编译:
Run Code Online (Sandbox Code Playgroud)int i = 42; cin << i; // this code would be legal if the conversion to bool were not explicit!该程序尝试在输入流上使用输出运算符。没有
<<定义 foristream,所以代码几乎肯定是错误的。然而,这个代码可以使用布尔转换操作符转换cin到bool。然后将生成的 bool 值提升为 int 并用作左移运算符的内置版本的左侧操作数。提升的布尔值(1 或 0)将左移 42 个位置。
输入流可以转换为表示流内部状态(成功或失败)的布尔值。我们曾经这样做:
while(std::cin >> str)...
Run Code Online (Sandbox Code Playgroud)
那么为什么不应该编译呢?
int x = 0;
std::cin << x;
Run Code Online (Sandbox Code Playgroud)
如果我使用显式转换,它会起作用:
(bool)cin << 5; // works although bad
Run Code Online (Sandbox Code Playgroud) 以下不会编译:
#include <memory>
class A;
bool f() {
std::shared_ptr<A> a;
return a;
}
int main()
{
f();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
并失败:
Compilation failed due to following error(s).main.cpp: In function ‘bool f()’:
main.cpp:13:12: error: cannot convert ‘std::shared_ptr’ to ‘bool’ in return
return a;
Run Code Online (Sandbox Code Playgroud)
标准(我认为)不允许在这里进行隐式转换的原因是什么?
我有一些可以设置或不设置的类:
Class obj;
Run Code Online (Sandbox Code Playgroud)
我希望它的值在逻辑中使用时返回是否已设置:
if ( obj )
obj.Clear();
if ( !obj )
obj.Set( "foo" );
Run Code Online (Sandbox Code Playgroud)
我想添加到 bool 的隐式转换,但我想知道 int 是否是必要的,或者是否有更好的方法来解决这个问题。
c++ ×8
c++11 ×3
boolean ×2
explicit ×2
c++-faq ×1
cin ×1
constructor ×1
if-statement ×1
oop ×1
return-type ×1
shared-ptr ×1
variables ×1