Here is what troubles me: I have an overloaded operator << in a header file FAPPDebug.h such as:
QTextStream& operator << (QTextStream& a, FAPPDebug& b);
and the implementation in FAPPDebug.cpp:
QTextStream& operator << (QTextStream& a, FAPPDebug& b)
{
QString msg = *b.stream->ts.string(); // just take the message from b
a << msg;
return a;
}
and the corresponding function call:
QTextStream(stdout) << (debug() << "Quitting because application object is not set.");
regardless of how weird this looks, this compiles (and works!) under Windows with MSVC2010
debug() is just a macro to create a FAPPDebug object from the current location. Please note the extra set of () around (debug() << "...") without that it is not producing what I want.
On the other end under Linux with g++ 4.4 I get the following error:
MessageBroker.cpp:91: error: no match for ‘operator<<’ in
‘QTextStream(stdout,
QFlags((QIODevice::OpenModeFlag)3u)) <<
((FAPPDebug*)((FAPPDebug*)FAPPDebug(417, ((const
char*)"MessageBroker.cpp"), ((const char*)(& PRETTY_FUNCTION)),
(LogLevel)7u).FAPPDebug::operator<<(((const
char*)"Module")))->FAPPDebug::operator<<(((const QString&)((const
QString*)(&
ModuleBase::getModuleDescription()())))))->FAPPDebug::operator<<(((const
char*)"Quitting because application object is not set."))’
/usr/local/Trolltech/Qt-4.8.2/include/QtCore/qtextstream.h:184: note:
candidates are: FAPPDebug.h:94: note: QTextStream&
operator<<(QTextStream&, FAPPDebug&)
(There are a lot of candidates, I have just kept what is important)
I have modified the function call to be:
::operator << (QTextStream(stdout), debug() << "Failed to schedule application startup.");
and I get the error message:
MessageBroker.cpp: In member function ‘bool
MessageBroker::init(Application*, const QString&)’:
MessageBroker.cpp:91: error: no matching function for call to
‘operator<<(QTextStream, FAPPDebug&)’
/usr/local/Trolltech/Qt-4.8.2/include/QtCore/qchar.h:396: note:
candidates are: QDataStream& operator<<(QDataStream&, const QChar&)
/home/ferenc/work/trunk/Core/Common/FAPPDebug.h:94: note:
QTextStream& operator<<(QTextStream&, FAPPDebug&)
so as you can see the correct function is found every time (yes, the FAPPDebug.h header is included in MessageBroker.cpp), but the "more standard compliant" compiler failed to use it. I have the feeling that this is a glitch in my comprehension of the standard somewhere, so I am asking for your help to find it.
EDIT: the operator is declared as friend in class FAPPDebug
EDIT2: The debug() is a macro, and is defined like:
#define debug() FAPPDebug(__LINE__, __FILE__, __PRETTY_FUNCTION__, LOG_DEBUG)
ie. it just created a FAPPDebug object with parameters indicating the current position.
Thanks!
f.
I think the problem may be that your insertion operator accepts a reference (lvalue) as the first parameter, as expected, but you are trying to pass a rvalue created automatically from a constructor. Think about it, how do you expect an automatically created QTextStream(stdout) to live a sequence of calls of the type, QTextStream(stdout) << a << b << c. In truth, this is x << a then x << b then x << c. For it to live that happening in a single sentence I think both the first and the return must be const references, which is able to pin your rvalue.
Or you may just declare a variable like QTextStream qout(stdout), and use qout instead.
Shouldn't the second parameter to your operator<< be FAPPDebug
const&? You can't initialize a non-const reference with a temporary,
even if some compilers still fail to detect the error.
If you look closely, the functions which compiler see used and what you have defined aren't the same.
What it sees:
no matching function for call to ‘operator<<(QTextStream, ...
What it has defined
QTextStream& operator<<(QTextStream&, ...
It seems like temporary object couldn't be passed as non-const reference.
So either change it to QTextStream const& or use rvalue reference.
EDIT: Oh well, I just understood that stream passed as first parameter can't really be const. Using rvalue reference or just catching by value, if it's possible, seems to me the only way to do it now. It's your (debug() ...) object that's causing the problem.
I had this problem, and it is a problem of any beginner in C++.
QTextStream& operator << (QTextStream& a, FAPPDebug& b);
This is your declaration, but your usage is:
QTextStream(stdout) << (debug() << "Quitting because application object is not set.");
I assume you have your FAPPDEbug object having an operator that lets it use operator on const char pointer. so then this becomes this
QTextStream(stdout) << FAPPDebugObject;
And you compiler wont find it in a case if FAPPDebugObject was not returned as a reference, because you are asking for a reference arg in the next operator.
I hope it made sense to you, or anyone looking for a solution.
Related
I declare a logging function with an info-string as default parameter.
void LogError(ErrorEnum error, string& infoStr = (string&)"")
When the function is called without the additional string i get an unhandled exception while trying to write into a log stream in such a way:
ofstream mystream;
//do some stuff
mystream<< "Error " << infoStr << " failed!" << endl;
If ich change the default parameter to (string&)string(), the exception does not occur anymore. Debugging with VS2013 shows that in both cases the value of infoStr is "".
So where is the difference in the between the two declarations?
In the first case, you are basically casting from char const (&) [1] to string&. That is obviously not valid. std::string is a class, it is not singleton array of characters, hence the exception. In the second case you are casting a temporary from rvalue to lvalue. That is dubious but since the referenced value is actually of the same type it works out fine.
I'm trying to write my own stream class. It will do something with the input and pass it on to std::cout. So far I passed functions operating on the stream (e.g. std::endl) on to cout. Now, I want to check for std::endl input and perform some actions, if it occurs. I have implemented the behaviour like this
DebugStream& DebugStream::operator<< (ostream& (*pfun)(ostream&))
{
if(pfun == std::endl)
{
// do something
}
pfun(cout);
return *this;
}
Which results into
/path/to/file.cpp:89:24: error: assuming cast to type ‘std::basic_ostream<char>& (*)(std::basic_ostream<char>&)’ from overloaded function [-fpermissive]
using the GCC compiler. I don't know, how to compare the function pointer against the std::endl function. Maybe this problem is related to the template nature of the std::endl function? Or because it's inline?
The reason you get a warning is that std::endl is a template function. You can fix this error by forcing a comparison to a template instance of a particular type through a cast, like this:
typedef ostream& (*io_manip_ptr_t)(ostream&);
void demo(io_manip_ptr_t pfun) {
if (pfun == (io_manip_ptr_t)&endl) {
cout << "Hi" << endl;
}
}
Demo.
Note: Even though the work-around is available, this is only a workaround, not a solid solution, because comparing function pointers to decide on functionality introduces a very serious problem: your functions get reduced to an enum, so your code becomes impossible to extend from the outside.
void main() {
cout << "Hello World" << endl;
}
I'm not allowed to make any change to the above main function while the output on the screen need to be sth like:
initialize
Hello World
clean up
My thought is that I need to use overloading operator of << . However I need to know what's the data type of the double quoted string following the operator << , otherwise I will not make full use of my redefined << operator. Anyone any thought?
The type of the literal is "array of {suitable number of} const chars", but a better approach might be to have some kind of global object.
(Adding an overload for the array would probably not even work, because the existing overload for char const * would be getting in the way.)
You could redefine std::ostream& operator<< (std::ostream&, const char*). There's one huge problem with this approach: It is undefined behavior. The standard library already defines that function, and you are not allowed to redefine standard library functions.
The key to solving this problem is to recognize that cout is in the global namespace. The solution is simple: Write your own class that overloads operator<< and make a global variable named cout that is an instance of this class. That way you are not running into undefined behavior.
You'll also need to do something with that endl that is in the global namespace.
Your code should look something like
// Insert your code here.
int main () {
cout << "Hello World" << endl;
}
Since this looks like homework, I'll leave the rest up to you.
The type of a string literal is char const[n] where n is the number of characters in the string literal, including the terminating null character. Note, however, that the solution to your problem isn't overloading operator<<(). Instead, you should look at constructors, destructors, and variable with static live-time.
While trying to answer this question I found without () (which invokes "C++ most vexing parse") the output of g++ is 1 (Can be seen here: http://ideone.com/GPBHy), where as visual studio gives a linker error. I couldn't understand how the output can 1, any clues?
As the answers to the question already explain, due to the "Most Vexing Parse" the statement instead of defining an object named str with the two istream_iterators to specify its initializers, is parsed as a declaration of a function named str that returns a string.
So a simple version of the program resolves to, this online sample:
#include<iostream>
void doSomething()
{
}
void (*ptr)()=&doSomething;
int main()
{
std::cout << ptr << "\n";
std::cout << doSomething;
return 0;
}
Output:
1
1
Note that there is no overloaded operator << that takes an std::ostream and a function pointer as arguments, this is because there can be any number of user defined function types and ofcourse a standard overloaded api cannot account for them all.
Given that the compiler tries to find the best match among the existing overloads which happens to be bool (a function pointer is implicitly convertible to bool[#1]).
In particular,
basic_ostream& operator<< (bool& val );
Since the function pointer points to something and not null, the value is printed as 1.
[#1]C++03 4.12 Boolean conversions
1 An rvalue of arithmetic, enumeration, pointer, or pointer to member type can be converted to an rvalue of type bool.
I hav been going over some old hw assignments from a class last semester.
This was a given print function to print out linked list objects.
I don't understand why the overloaded operator takes two parameters and one being an
os object. When we were printing out actual linked list objects on main.cpp, we didn't
need to pass an os object. Also, why is it returning os? Why can't we just use cout
instead of "os <<" ?
Thank you!
template <class T>
void List<T>::print(ostream & os) const
{
os << "<";
ListNode * curr = head;
while (curr != NULL) {
os << " " << curr->data;
curr = curr->next;
}
os << " >";
}
// overloaded operator<<
template <class T>
ostream & operator<<(ostream & os, const List<T> & list)
{
list.print(os);
return os;
}
By the way the question was asked and how basic it is, I'm going to try to give a very simplistic (albeit rather informal and not so pedantic) answer.
I don't understand why the overloaded operator takes two parameters
and one being an os object
operator<< is a binary operator. It has a left-hand side and a right-hand side. When you write:
cout << 123;
You are invoking this operator with two operands (arguments): 'cout' on the left and an integer, '123', on the right.
When we were printing out actual linked list objects on main.cpp, we
didn't need to pass an os object.
Your print function is a member function or operator of a class. That would implicitly deduce that the first argument, crudely speaking, does not need to be explicitly passed since you already have the 'this' pointer to work with for your list object. That's not the case with non-member operators as you don't have an implicitly deduced 'this' object to work with already for the left-hand side operand.
When you write code like this:
my_list.print(cout);
You can think of it as actually passing in two arguments, 'my_list' and 'cout'. Even though you don't write it explicitly, you have access to 'my_list' through 'this' along with its members. That's not the case if you wrote the print function as a non-member, like so:
template <class T>
void print(const List<T>& my_list, ostream& os);
That's also the case with your operator which is not a member function.
Also, why is it returning os?
Returning a reference to ostream is what allows us to write statements like this:
cout << "hello " << "world";
First we invoke operator<<(cout, "hello ") which then gives us another ostream reference to work with which then allows us to proceed to invoke operator<<(cout, "world"). If it returned void, for example, it would not allow us to invoke that operator twice in one statement since we'd be trying to output "world " with void as the left-hand operand.
Why can't we just use cout instead of "os <<" ?
cout basically implements the ostream interface. So does ofstream, ostringstream, and other types of output streams. By writing it in terms of the basic interface required and not some specific ostream derivative, you allow the code you write to work with stdio streams, file streams, stream streams, and others. Basically it makes your code very general and reusable which is something you should strive to do when practical. You'll learn about this subject more as you tackle the concept of polymorphism.
Because it is a global non-member function. With the member function version, the first parameter is implicitly the invoking object, this. That means that your class always has to be on the left hand side. With the non-member function, it's an explicit parameter; this way, you can specify any type you want, and overload operators for classes that you can't modify the source for (as long as at least one parameter is a user-defined type).
The reason why you use os is so that it works with file streams and everything (anything that inherits from ostream), instead of just cout.
It returns os so that you can do more operator<< calls on the return value. This enables operator chaining, like w << x << y << z, which is the same as operator<<(operator<<(operator<<(w, x), y), z). If you return void or something, you would have to stop at w << x because you can't do anything with the return value of void.
I don't understand why the overloaded operator takes two parameters and one being an os object. When we were printing out actual linked list objects on main.cpp, we didn't need to pass an os object.
Yes you did: when you say cout << x, you are passing cout and x to operator<<.
Also, why is it returning os?
To make cout << x << y possible. This is parsed as (cout << x) << y, i.e. it inserts y into the return value of cout << x.
Why can't we just use cout instead of "os <<" ?
Because sometimes you want to output to another stream than standard output.
When we were printing out actual linked list objects on main.cpp, we
didn't need to pass an os object.
Yes, you did.. something like cout << obj;, where cout is the os output stream.
Also, why is it returning os? Why can't we just use cout instead of "os <<" ?
This allows chaining: cout << obj << " " << obj2;
Why can't we just use cout instead of "os <<" ?
That would hard-wire the output stream, so you couldn't write to file or any other output.