我得到这个错误:“错误:没有上下文类型信息的重载函数”。
cout << (i % 5 == 0) ? endl : "";
我正在做的事情是可能的吗?是我做错了,还是我必须重载<<操作符?
发布于 2011-04-20 06:50:13
它不会以这种方式工作(即使您修复了优先级错误)。这里有两个问题,第二个比第一个更严重。
第一个问题是std::endl
是一个模板。它是一个函数模板。模板必须是专门化的。为了专门化该模板,编译器必须知道(推断)模板参数。当你这样做的时候
std::cout << std::endl;
编译器使用operator <<
期望的特定函数指针类型来确定如何专门化std::endl
模板。
然而,在您的示例中,您实际上是通过将std::endl
移动到operator <<
子表达式中来将std::endl
与?:
“分离”的。现在编译器必须首先编译这个表达式
(i % 5 == 0) ? endl : ""
无法编译此表达式,因为编译器不知道如何专门化std::endl
模板。在没有任何上下文的情况下,无法推断模板参数。
例如,这个简单的C++程序
#include <iostream>
int main() {
std::endl;
}
也会因为同样的原因而无法编译:没有上下文,编译器就不知道如何实例化std::endl
。
您可以通过显式指定模板参数来“帮助”编译器解决该问题
(i % 5 == 0) ? endl<char, char_traits<char> > : "";
这将显式地告诉编译器如何实例化endl
。您收到的原始错误消息将会消失。
然而,这将立即揭示该表达式的第二个更严重的问题: specialized 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
发布于 2011-04-20 06:47:24
?
运算符的两个参数必须是相同类型的(至少在潜在的提升、隐式构造函数、强制转换运算符等加入之后)。std::endl
实际上是一个函数模板(详细信息如下),然后流调用它来影响其状态:它不像""
那样是字符串文字。
所以,你不能准确地做到这一点,但你可能可以得到你真正想要的行为-考虑是否...
expr ? "\n" : ""
...meets你的需要-它是类似的,但不会刷新流(我的意思是,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'))); }
发布于 2011-04-20 06:47:34
如果other.
endl
是一个模板,而上下文没有提供足够的信息可供选择,则?:
的两个备选方案必须具有相同的类型,或者其中一个可以转换为模板。所以它甚至没有类型。(这是您的错误消息)。https://stackoverflow.com/questions/5726427
复制相似问题