(a==1)&&(a==2)&&(a==3) 的计算结果为 true 吗?(它有用吗?
Can (a==1)&&(a==2)&&(a==3) evaluate to true? (and can it be useful?)
灵感来自另一个关于java脚本语言的问题。可以表达
(a==1)&&(a==2)&&(a==3)
评估为真C++?(如果是这样,它真的有用吗?
是的,它可以:
class Foo
{
public:
bool operator==(int a)
{
return true;
}
};
然后,让a
属于Foo
型,瞧。
这真的有用吗?我真的不认为它有用不。
的计算结果可以在C++中为 true 吗?
是的,没有什么是不可能的...
struct A {
int x = 0;
};
bool operator==(A& a, int num) {
return ++a.x == num;
}
然后:
if ((a == 1) && (a == 2) && (a == 3)) {
std::cout << "meow" << std::endl;
}
打印meow
.
但是我不知道这种奇怪的重载有任何实际用途,希望永远不会在生产中看到这样的代码。
可能有些用处。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Foo {
std::vector<int> v = {1,2,3};
};
bool operator==(const Foo& foo, int i) {
return std::any_of(foo.v.begin(), foo.v.end(), [=](int v){ return v == i; });
}
int main() {
Foo a;
if (a==1 && a==2 && a==3)
cout << "Really??" << endl;
return 0;
}
正如之前注意到的那样,这个技巧可以用volatile
来执行。与更换操作员相比,这是更诚实的方法。让我们使用两个线程:
volatile int a;
void changingValue(){
std::srand(unsigned(std::time(0)));
while (true) {
a = (rand() % 3 + 1);
}
}
void checkingValue(){
while (true) {
if (a == 1 && a == 2 && a == 3) {
std::cout << "Good choice!" << std::endl;
}
}
}
int main() {
std::thread changeValue = std::thread(changingValue);
changeValue.detach();
std::thread checkValue = std::thread(checkingValue);
checkValue.detach();
while (true){
continue;
}
}
此外,在我的情况下,这段代码运行良好,没有volatile
声明。据我了解,它应该取决于编译器和处理器。如果我错了,也许有人可以纠正它。
其他尚未提及的事情(来源):
a
可能重载了operator int()
,用于隐式转换为int
运算符(而不是其他答案所涵盖的operator==
)。a
可能是预处理器宏。
后者的例子:
int b = 0;
#define a ++b
if ((a==1)&&(a==2)&&(a==3))
std::cout << "ahan";
运算符重载和宏是解决此类谜语的微不足道的解决方案。
如果是这样,它真的有用吗?
好吧,有一些想象力...我能想到的一个可能的用例是单元测试或集成测试,在这些用例中,您希望确保某些类的重载operator==
正常工作,并且如果它报告不同操作数的相等性,您肯定知道它工作不正确,而不应该这样做:
class A {
public:
A(int i);
bool operator==(int i) const;
// ...
};
A a(1);
if ((a==1)&&(a==2)&&(a==3)) {
// failed test
// ...
}
我假设需求是一个没有未定义行为的有效程序。否则,只需引入数据竞赛之类的东西,然后等待合适的情况发生。
简而言之:是的,对于用户定义的类型是可能的。C++具有运算符重载,因此 JavaScript 问题中的相关答案适用。a
必须是用户定义类型,因为我们与整数进行比较,并且您无法实现所有参数都是内置类型的运算符重载。鉴于此,一个简单的解决方案可能如下所示:
struct A {}
bool operator==(A, int) { return true; }
bool operator==(int, A) { return true; }
这样的东西有用吗?正如问题所述:几乎可以肯定不是。在其通常上下文中使用的运算符符号隐含了强烈的语义含义。在==的情况下,这就是相等比较。改变这个含义会产生一个令人惊讶的API,这很糟糕,因为它鼓励了不正确的使用。
但是,有些库显式使用运算符用于完全不同的目的。
- 我们有来自 STL 本身的一个例子:iostream 对
<<
和>>
的使用。 - 另一个是提升精神。他们使用运算符以类似 EBNF 的语法编写解析器。
对运算符符号的这种重新定义很好,因为它们非常明显地表明,通常的运算符符号用于非常不同的目的。
只是为了展示我自己的想法。我在想一些数据结构,如流缓冲区或环形缓冲区。
我们可以通过模板继承"隐藏运算符",数据结构本身不会改变任何内容,但所有检查都将在模板超类中完成。
template<class C>
class Iterable{
C operator==(int a);
public:
Iterable(){pos = 0;}
int pos;
};
template<class C>
class Stream : public Iterable<Stream<C>>{
public:
Stream(C a){ m[0] = a; }
C m[32];
int operator==(int a){
return (m[this->pos++]==a); }
};
int main(){
Stream<int> a(1);
a.m[0] = 1; a.m[1] = 3; a.m[2] = 2;
if(a==1 && a==3 && a==2)
std::cout<<"Really!?"<<std::endl;
return 0;
}
例如,在这种情况下,整数的 == 可能是"是此 ID 号流中的下一个数据包/元素"的快捷方式。
- 无论条件是否为true,if总是在c++中执行
- 为什么需要复制构造函数,在哪些情况下它们非常有用
- flutter:即使shouldRepaint()返回true,自定义画家也不会重新绘制
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 其中降频广播实际上是有用的
- Arduino-C++ bool 不会从 false 变为 true
- 如何使布尔变量仅在设置为 true 时才为真?
- C++ 如果在 if 为 true 之后运行,为什么还会这样做
- 为什么组合的上限和下限比较的计算结果总是为 true?
- 既然我们有内联变量,extern const 还有用吗?
- 对于完成布尔值设置为 true 后未停止的循环
- 为什么'typeid(x) == typeid(y)'的计算结果为 true,其中 'x' 和 'y' 分别是 T 和 T& 类型的 id-表达式?
- OLE DB 大容量复制操作始终将 true 加载到位列中
- cin.fail() not returning true
- 函子还有更有用的用例吗?
- Fmod 函数清楚地输出一个预期的双精度值,但 if(fmod == 预期的双精度值)的计算结果不是 true
- 如何使用boost定义布尔类,可能的值应该是TRUE或FALSE?
- `__declspec(novtable)`没有用吗
- P1008("prohibit aggregates with user-declared constructors")在实践中什么时候有用?
- (a==1)&&(a==2)&&(a==3) 的计算结果为 true 吗?(它有用吗?