C++: cout带有一个三重if语句

C++ : cout with a terenary if-statement

本文关键字:三重 if 语句 cout 有一个 C++      更新时间:2023-10-16

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

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

我所做的是可能的;是我做错了吗,还是我必须让<<运营商吗?

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

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

std::cout << std::endl;

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

然而,在您的示例中,您通过将std::endl移动到?:子表达式中,基本上将std::endloperator <<"分离"。现在编译器必须先编译这个表达式

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

这个表达式不能被编译,因为编译器不知道如何专门化std::endl模板。没有任何上下文就无法推断模板参数。

例如,下面这个简单的c++程序
#include <iostream>
int main() {
   std::endl;
}

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

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

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

这将显式告诉编译器如何实例化endl。您得到的原始错误信息将会消失。

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

那么,基本上,你在这里遇到的最新问题是如果你试图做像

这样的事情
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

?操作符的两个参数必须具有相同的类型(至少在潜在的提升,隐式构造函数,强制转换操作符等开始之后)。std::endl实际上是一个函数模板(详情如下),然后流调用它来影响它的状态:它不像""那样是一个字符串字面值。

所以,你不能完全做到,但你可能会得到你真正想要的行为-考虑是否…
expr ? "n" : ""

…满足您的需求——它类似,但不会刷新流(IMHO, std::cout通常应该尽可能少地刷新——特别是低级库代码——因为这样可以提供更好的性能)。(它也更灵活,例如expr ? "whatevern" : ""/不能将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'))); }
  • ?:的两个备选项必须具有相同的类型,或者一个可以转换为另一个

  • endl是一个模板,上下文没有提供足够的信息供选择。它甚至没有类型。

  • 正如其他人已经说过的,绑定不是您所期望的。

这很有可能(我自己也怀疑)。然而,它也很愚蠢,实际上就像:

cout << "";

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

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

你不应该仅仅为了使用三元制而使用它。实际上,您不应该仅仅为了使用而使用任何语言特性。我不写这样的代码:

if (1) { doSomething(); }

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

试试这个,它可以工作:

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

要使其正常工作,应该是这样的:

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

操作符<<优先级高于?:。试试这个:

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