C++:带有terenary if语句的cout

9 c++ if-statement cout

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

cout << (i % 5 == 0) ? endl : "";
Run Code Online (Sandbox Code Playgroud)

我正在做什么; 我只是做错了,还是我必须重载<<运算符?

AnT*_*AnT 31

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

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

std::cout << std::endl;
Run Code Online (Sandbox Code Playgroud)

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

然而,在你的榜样,你基本上是"独立"的std::endloperator <<通过移动std::endl到一个?:子表达式.现在编译器必须首先编译这个表达式

(i % 5 == 0) ? endl : ""
Run Code Online (Sandbox Code Playgroud)

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

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

#include <iostream>
int main() {
   std::endl;
}
Run Code Online (Sandbox Code Playgroud)

也会因为同样的原因而无法编译:没有上下文,编译器不知道如何实例化std::endl.

您可以通过显式指定模板参数来"帮助"编译器解决问题

(i % 5 == 0) ? endl<char, char_traits<char> > : "";
Run Code Online (Sandbox Code Playgroud)

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

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

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

cout << (i % 5 == 0 ? 10 : "Hi!");
Run Code Online (Sandbox Code Playgroud)

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

所以,你试图写的表达式不能这样写.在不尝试使用?:运算符的情况下重写它.


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

$ 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
Run Code Online (Sandbox Code Playgroud)

  • +1如果它是明确选择的,那么它仍然会失败,因为函数指针和字符串文字没有任何共同之处. (2认同)

Ton*_*roy 15

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

所以,你不能这样做究竟,但你可能可以得到你真正想要的行为-考虑是否...

expr ? "\n" : ""
Run Code Online (Sandbox Code Playgroud)

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

例如,对于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'))); }
Run Code Online (Sandbox Code Playgroud)


Mic*_*ael -1

运算符的<<优先级高于?:。尝试这个:

cout << ((i % 5 == 0) ? endl : "");
Run Code Online (Sandbox Code Playgroud)

  • 你自己尝试过吗?它会编译吗? (6认同)