流操作符<<输出由编译器解释为二进制运算符<<向左移位?

时间:2018-03-17 10:28:19

标签: c++

试图用Bjarne Stroustrup书中的一个简单的练习来完成,这让我很自然地疯了......

#include <iostream>
using namespace std;

#define smaller(a,b)    ((a)<(b)) ? (a) : (b)
#define larger(a,b)     ((a)<(b)) ? (a) : (b)

int main()
{
    int a, b;
    while (cin >> a >> b) {
        cout << "The smaller value is: " << smaller(a,b)
             << "\nThe larger value is: " << larger(a,b); 
    }
}

当然,出了点问题,猜猜是什么?这里:

$ g++ -std=c++0x -o un4 un4.cpp
un4.cpp: In function ‘int main()’:
un4.cpp:13:17: error: invalid operands of types ‘int’ and ‘const char [23]’ to binary ‘operator<<’
              << "\nThe larger value is: " << larger(a,b); 
                 ^

欣赏,如果有人解释,什么是魔法

1 个答案:

答案 0 :(得分:2)

宏不是函数,它们只是参数化文本替换。因此,您需要防止使用不同优先级的运算符解析表达式。一个非常常见的模式是始终将完整宏括起来,如:

#define smaller(a,b)    ( ((a)<(b)) ? (a) : (b) )
#define larger(a,b)     ( ((a)<(b)) ? (a) : (b) )

- - - - - - - - 编辑

当您编写something << smaller(x,y) << anotherthing编译器时,只需将文本 smaller(x,y)替换为其完全文本扩展(+宏参数替换),因此你的情况导致:

something << ((x)<(y)) ? (x) : (y) << anotherthing

并且这不是您想要的,因为<<的优先级高于三元?:,这意味着(添加了括号):

( something << ((x)<(y)) ) ? (x) : ( (y) << anotherthing )

并且在此表达式中,问题是子表达式(y) << anotherthing,在您的情况下,3 << "foo"类似于正确的表达式。

更正宏后,示例表达式扩展为:

something << ( ((x)<(y)) ? (x) : (y) ) << anotherthing

并评估为:

( something << ( ((x)<(y)) ? (x) : (y) ) ) << anotherthing

这就是你想要的。

宏非常奇怪,鼓励你不要使用它们。