C ++:带有三元if语句的cout

时间:2011-04-20 06:38:20

标签: c++ if-statement cout

我得到这个错误:“错误:没有上下文类型信息的重载函数”。

cout << (i % 5 == 0) ? endl : "";

我正在做的事情;我只是做错了,还是我必须重载&lt;&lt;操作

7 个答案:

答案 0 :(得分:31)

它不会那样工作(即使你修正了优先级错误)。这里有两个问题,第二个问题比第一个问题更严重。

第一个问题是std::endl是一个模板。它是一个功能模板。模板必须是专门的。为了专门化该模板,编译器必须知道(推断)模板参数。当你这样做

std::cout << std::endl;

operator <<期望的特定函数指针类型是编译器用来确定如何专门化std::endl模板的方法。

然而,在你的例子中,你基本上是&#34;分离的&#34;将std::endl移动到operator <<子表达式,std::endl中的?:。现在编译器必须先编译这个表达式

(i % 5 == 0) ? endl : ""

由于编译器不知道如何专门化std::endl模板,因此无法编译此表达式。没有任何上下文,没有办法推断出模板参数。

例如,这个简单的C ++程序

#include <iostream>
int main() {
   std::endl;
}
由于同样的原因,

也无法编译:没有上下文,编译器不知道如何实例化std::endl

你可以帮助&#34;编译器通过明确指定模板参数来解决问题

(i % 5 == 0) ? endl<char, char_traits<char> > : "";

这将明确告诉编译器如何实例化endl。您收到的原始错误消息将消失。

然而,这将立即揭示该表达式的第二个更严重的问题:专用endl是一个函数(在此上下文中衰减为函数指针),而""是字符串文字。您不能在?:运算符中混合函数指针和字符串文字。这些类型不兼容。它们不能一起用作三元?:的第2和第3操作数。编译器将发出关于第二个问题的不同错误消息。

所以,基本上,你在这里遇到的最新问题就好像你试图做了像

这样的事情
cout << (i % 5 == 0 ? 10 : "Hi!");

由于表达式无法编译的原因相同,因此无法编译。

因此,您尝试编写的表达式无法以这种方式编写。重写它而不尝试使用?:运算符。


作为支持,请参阅以下成绩单:

$ cat qq.cpp
#include <iostream>
using namespace std;
int main (void) {
    int i = 5;
    cout << ((i % 5 == 0) ? endl : "");
    return 0;
}

$ g++ -o qq qq.cpp
qq.cpp: In function 'int main()':
qq.cpp:5: error: overloaded function with no contextual type information

答案 1 :(得分:15)

?运算符的两个参数必须属于同一类型(至少在潜在的促销,隐式构造函数,转换运算符等等之后)。 std::endl实际上是一个函数模板(详见下文),然后流调用它来影响其状态:它不是像""那样的字符串文字。

所以,你不能完全,但你可能会得到你真正想要的行为 - 考虑是否......

expr ? "\n" : ""

...满足您的需求 - 它类似但不会刷新流(恕我直言,std::cout通常应该尽可能不频繁地刷新 - 特别是通过低级库代码 - 因为它提供了更好的性能) 。 (它也更灵活,例如expr ? "whatever\n" : "" /无法将endl附加到字符串文字。)

E.g。对于GCC 4.5.2,endl是:

template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>& 
    endl(basic_ostream<_CharT, _Traits>& __os)
    { return flush(__os.put(__os.widen('\n'))); }

答案 2 :(得分:3)

  • ?:的两个选项必须具有相同的类型,或者可以转换为另一个。

  • endl是一个模板,上下文没有提供足够的信息供您选择。所以它甚至没有一种类型。 (这是你的错误信息)。

  • 正如其他人已经说过的那样,绑定不是你期望的那种。

答案 3 :(得分:2)

很可能(我自己也怀疑)。然而,它也是愚蠢的,有效地愚蠢如下:

cout << "";

在这种情况下你应该做的事情很简单:

if (i % 5 == 0) cout << endl;

您不应仅仅为了使用它而使用三元组。实际上,您不应仅仅为了使用它而使用任何语言功能。我不写代码如下:

if (1) { doSomething(); }

只是因为我可以。一个简单的doSomething();要好得多。

答案 4 :(得分:2)

试试这个,它有效:

cout << ((i % 5 == 0) ? "\n" : "");

答案 5 :(得分:1)

这就是它应该如何使其正常工作:

cout << ((i % 5 == 0) ? '\n' : " ");

答案 6 :(得分:-1)

运营商<<的优先级高于?:。试试这个:

cout << ((i % 5 == 0) ? endl : "");