C ++: cout with if-statement terminator

I get this ERROR: "error: overloaded function without context type information."

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

I do what I do; Am I just doing it wrong, or do I have to overload the <<statement?

+7
source share
7 answers

This will not work (even if you correct the precedence error). You have two problems here, the second more serious than the first.

The first problem is that std::endl is a template. This is a function template. The template must be specialized. To specialize this template, the compiler must know (output) the arguments of the template. When you do

 std::cout << std::endl; 

the specific type of function pointer expected by operator << is what the compiler uses to figure out how to specialize the std::endl .

However, in your example, you essentially "disconnected" std::endl from operator << by moving std::endl to a subexpression ?: . Now the compiler must first compile this expression

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

This expression cannot be compiled because the compiler does not know how to specialize the std::endl . There is no way to infer template arguments without any context.

For example, this simple C ++ program

 #include <iostream> int main() { std::endl; } 

it also fails to compile for the same reason: without context, the compiler does not know how to create an instance of std::endl .

You can "help" the compiler solve the problem by specifying the template arguments explicitly

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

This will explicitly tell the compiler how to instantiate the endl . The original error message you received will disappear.

However, this immediately reveals a second, more serious problem with this expression: the specialized endl is a function (which in this context turns into a pointer to a function), while "" is a string literal. You cannot mix function pointer and string literal in such an operator ?: These types are incompatible. They cannot be used together as the 2nd and 3rd operand of the ternary ?: . The compiler will give another error message about this second problem.

So basically, this is the last problem that you have here, as if you were trying to do something like

 cout << (i % 5 == 0 ? 10 : "Hi!"); 

This does not compile for the same reason that your expression does not compile.

Thus, the expression you are trying to write cannot be written this way. Rewrite it without trying to use the ?: Operator.


For support, see the following transcript:

 $ 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 
+31
source

Two operator arguments ? must be of the same type (at least after potential promotions, implicit constructors, casting operators, etc.). std::endl is actually a function template (details below), which then calls the stream to affect its state: it is not a string literal, for example, "" .

So you cannot do it for sure, but you can probably get the behavior you really want - think ...

 expr ? "\n" : "" 

... meets your needs - it is similar, but does not clear the stream (IMHO, std::cout should usually blush as rarely as possible, especially with the help of low-level library code, as this provides better performance). (It is also more flexible, for example expr ? "whatever\n" : "" / cannot add endl to a string literal.)

eg. for 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'))); } 
+15
source
  • Two alternatives ?: Must be of the same type or one must be convertible to another.

  • endl is a template, and the context does not provide enough information to select. So he doesn't even have a type. (This is your error message).

  • As already mentioned, the binding is not what you expect.

+3
source

Perhaps this is possible (I doubt it myself). However, it is also stupid, effective, as stupid as:

 cout << ""; 

What you should do in this case is simply:

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

You should not use the trinity just for the sake of using it. In fact, you should not use any language feature just for the sake of using it. I am not writing code like:

 if (1) { doSomething(); } 

just because i can. Simple doSomething(); much better.

+2
source

Try it, it works:

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

Here's how it should look so that it works correctly:

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

The operator << has a higher priority than ?: . Try the following:

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

All Articles