When I types the following as a stand-alone line:
std::endl;
I got the following error:
statement cannot resolve address for overloaded function
Why is that? Cannot I write std::endl; as a stand-alone line?
Thanks.
std::endl is a function template. Normally, it's used as an argument to the insertion operator <<. In that case, the operator<< of the stream in question will be defined as e.g. ostream& operator<< ( ostream& (*f)( ostream& ) ). The type of the argument of f is defined, so the compiler will then know the exact overload of the function.
It's comparable to this:
void f( int ){}
void f( double ) {}
void g( int ) {}
template<typename T> void ft(T){}
int main(){
f; // ambiguous
g; // unambiguous
ft; // function template of unknown type...
}
But you can resolve the ambiguity by some type hints:
void takes_f_int( void (*f)(int) ){}
takes_f_int( f ); // will resolve to f(int) because of `takes_f_int` signature
(void (*)(int)) f; // selects the right f explicitly
(void (*)(int)) ft; // selects the right ft explicitly
That's what happens normally with std::endl when supplied as an argument to operator <<: there is a definition of the function
typedef (ostream& (*f)( ostream& ) ostream_function;
ostream& operator<<( ostream&, ostream_function )
And this will enable the compiler the choose the right overload of std::endl when supplied to e.g. std::cout << std::endl;.
Nice question!
The most likely reason I can think of is that it's declaration is:
ostream& endl ( ostream& os );
In other words, without being part of a << operation, there's no os that can be inferred. I'm pretty certain this is the case since the line:
std::endl (std::cout);
compiles just fine.
My question to you is: why would you want to do this?
I know for a fact that 7; is a perfectly valid statement in C but you don't see that kind of rubbish polluting my code :-)
std::endl is a function template. If you use it in a context where the template argument cannot be uniquely determined you have to disambiguate which specialization you mean. For example you can use an explicit cast or assign it to a variable of the correct type.
e.g.
#include <ostream>
int main()
{
// This statement has no effect:
static_cast<std::ostream&(*)(std::ostream&)>( std::endl );
std::ostream&(*fp)(std::ostream&) = std::endl;
}
Usually, you just use it in a context where the template argument is deduced automatically.
#include <iostream>
#include <ostream>
int main()
{
std::cout << std::endl;
std::endl( std::cout );
}
std::endl is a manipulator. It's actually a function that is called by the a version of the << operator on a stream.
std::cout << std::endl
// would call
std::endl(std::cout).
http://www.cplusplus.com/reference/iostream/manipulators/endl/
You can't have std::endl by itself because it requires a basic_ostream as a type of parameter. It's the way it is defined.
It's like trying to call my_func() when the function is defined as void my_func(int n)
endl is a function that takes a parameter. See std::endl on cplusplus.com
// This works.
std::endl(std::cout);
The std::endl terminates a line and flushes the buffer. So it should be connected the stream like cout or similar.
#include<iostream>
#include<conio.h>
#include<string.h>
using namespace std;
class student{
private:
string coursecode;
int number,total;
public:
void getcourse(void);
void getnumber(void);
void show(void);
};
void student ::getcourse(){
cout<<"pleas enter the course code\n";
cin>>coursecode;
}
void student::getnumber(){
cout<<"pleas enter the number \n";
cin>>number;
}
void student::show(){
cout<<"coursecode is\t\t"<<coursecode<<"\t\t and number is "<<number<<"\n";
}
int main()
{
student s;
s.getcourse();
s.getnumber();
s.show();
system("pause");
}
Related
Surprisingly the below code compiles and runs without error on a variety of compilers and versions.
#include <iostream>
int main() {
endl(std::cout);
return 0;
}
Ideone link
How does it compile? I am sure there is no endl in global scope because a code like
std::cout << endl;
would fail unless using is used or else you need std::endl.
This behavior is called argument dependent lookup or Koenig lookup. This algorithm tells the compiler to not just look at local scope, but also the namespaces that contain the argument's type while looking for unqualified function call.
For ex:
namespace foo {
struct bar{
int a;
};
void baz(struct bar) {
...
}
};
int main() {
foo::bar b = {42};
baz(b); // Also look in foo namespace (foo::baz)
// because type of argument(b) is in namespace foo
}
About the piece of code referred in question text:
endl or std::endl is declared in std namespace as following:
template< class CharT, class Traits >
std::basic_ostream<charT,traits>& endl( std::basic_ostream<CharT, Traits>& os );
or
std::ostream& endl (std::ostream& os);
And cout or std::cout is declared as
extern std::ostream cout;
So calling std::endl(std::cout); is perfectly fine.
Now when one calls just endl(std::cout);, because the type of argument cout is from std namespace, unqualified supposedly a function endl is searched in std namespace and it is found succesfully and confirmed to be a function and thus a call to qualified function std::endl is made.
Further reading:
GOTW 30: Name Lookup
Why does 'std::endl' require the namespace qualification when used in the statement 'std::cout << std::endl;", given argument-dependent lookup?
It is the way the stream manipulators work.
Manipulators are functions that passed to operator << as arguments. Then within the operator they are simply called.
So you have function declared like
template <class charT, class traits>
basic_ostream<charT,traits>& endl(basic_ostream<charT,traits>& os);
and you pass its pointer to operator <<. And inside the operator that declared something like
ostream& ostream::operator << ( ostream& (*op)(ostream&));
the function is called.like
return (*endl )(*this);
Thus when you see record
std::cout << std::endl;
then std::endl is function pointer that is passed to the operator << as argument.
In the record
std::endl( std::cout );
namespace prefix before name endl may be omitted because in this case the compiler will use the Argument Dependent Lookup. Thus this record
endl( std::cout );
will compile successfully.
However if to enclose the function name in parentheses then ADL is not used and the following record
( endl )( std::cout );
will not compiled.
If you hand any pointer to a C++ stream, it's address will be put into the output. (Obviously unless there's a more specific output handler.)
void* px = NULL;
const char* ps = "Test";
FooType* pf = ...;
stringstream s;
s << ps << " " << px << " " << pf "\n";
s.str(); // yields, for example: "Test 0 AF120089"
This can be a problem, if the user erroneously was trying to actually print the value of FooType.
And it is also a problem when mixing wide char and narrow char, because instead of a compiler error, you'll get the address printed:
const wchar_t* str = L"Test! (Wide)";
// ...
cout << str << "\n"; // Ooops! Prints address of str.
So I was wondering - since I very rarely want to output a pointer value, would it be possible to disable formatting of pointer values, so that inserting a pointer value into a stream would result in a compiler error? (Outputting of pointer values could then be easily achieved by using a wrapper type or casting the pointer values to size_t or somesuch.)
Edit: In light of Neil's answer (disabling void* output by providing my own void* output operator) I would like to add that it would be nice if this also worked for tools such as Boost.Format, that make implicit use of the output operator defined in the std namespace ...
This gives a compilation error in g++ if the second and/or third output to cout is uncommented:
#include <iostream>
using namespace std;
ostream & operator << ( const ostream &, void * ) {
}
int main() {
int n = 0;
cout << 0;
// cout << &n;
// cout << (void *) 0;
}
A global template version of operator<< seems to work:
#include <iostream>
#include <boost/static_assert.hpp>
template<typename T>
std::ostream & operator<<(std::ostream & stream, T* value) {
BOOST_STATIC_ASSERT(false);
}
int main() {
int foo = 5;
int * bar = &foo;
std::cout << bar << std::endl;
}
Edit: This solution does not work as intended, as the template also captures string literals. You should prefer #Neil's solution.
Yes, you can cause a compilation error by providing your own overload of ostream's operator <<.
#include <iostream>
template <typename T>
std::ostream& operator << (std::ostream& s, T* p)
{
char ASSERT_FAILED_CANNOT_OUTPUT_POINTER[sizeof(p) - sizeof(p)];
}
int main()
{
int x;
int* p = &x;
cout << p;
}
Keep the operator << unimplemented for pointers.
template<typename T>
std::ostream& operator<<(std::ostream &stream, T* value);
Edit: Or better to put an invalid typename to get compiler error.
#include "stdafx.h"
#include "Record.h"
template<class T>//If I make instead of template regular fnc this compiles
//otherwise I'm getting an error (listed on the very bottom) saying
// that operator << is ambiguous, WHY?
ostream& operator<<(ostream& out, const T& obj)
{
out << "Price: "
<< (obj.getPrice()) << '\t'//this line causes this error
<< "Count: "
<< obj.getCount()
<< '\n';
return out;
}
int _tmain(int argc, _TCHAR* argv[])
{
vector<Record> v;
v.reserve(10);
for (int i = 0; i < 10; ++i)
{
v.push_back(Record(rand()%(10 - 0)));
}
copy(v.begin(),v.end(),ostream_iterator<Record>(cout, "\n"));
return 0;
}
//Record class
class Record
{
private:
int myPrice_;
int myCount_;
static int TOTAL_;
public:
Record(){}
Record(int price):myPrice_(price),myCount_(++TOTAL_)
{/*Empty*/}
int getPrice()const
{
return myPrice_;
}
int getCount()const
{
return myCount_;
}
bool operator<(const Record& right)
{
return (myPrice_ < right.myPrice_) && (myCount_ < right.myCount_);
}
};
int Record::TOTAL_ = 0;
Error 2 error C2593: 'operator <<' is ambiguous
The concept behind operator<<( ostream &, ... ) is that every class can have its own overload, handling that specific class in a way that make sense.
That means you get operator<<( ostream &, const Record & ) which handles Record objects, and operator<<( ostream &, const std::string & ) which handles standard strings, and operator<<( ostream &, const FooClass & ) which handles FooClass objects. Each of these functions knows how to handle the object type it has been declared for, because each of them requires a different handling. (E.g. getPrice() / getCount() for Record, or getFoo() / getBar() for FooClass.)
Your template is trampling roughshod over the whole concept. By defining it as a template function (which would match any class), you not only collide with the many definitions of operator<<() already in the standard / your codebase, but all possible overloadings.
How could the compiler decide whether to use operator<<( ostream &, const std::string & ) or your template? It cannot, so it throws up its hands in despair and gives up. That's what the error is telling you.
First, you need to read the error message more carefully. As an alternative, consider breaking the statement up, something like this:
out << "Price: ";
out << (obj.getPrice());
out << "\tCount: ";
out << obj.getCount();
out << '\n';
When you do, you'll realize that what's really causing the problem is not where you try to print out getPrice(), but where you try to print out "Price: ".
The problem is arising because the compiler doesn't know whether to use the normal overload to print out the string, or to use the template being defined to print it out. The latter would cause infinite recursion, and it couldn't actually compile since it requires an object on which you can/could call getPrice and getCount to compile correctly -- but it has a signature that matches, so the compiler says it's ambiguous, and that's the end of that.
The reason of the error is that your templated overload is conflicting with another templated overload, and there is no reason to prefer one template to another:
template<class charT, class traits>
basic_ostream<charT,traits>& operator<<(basic_ostream<charT,traits>&, const charT*);
template <class T>
basic_ostream<char, char_traits<char> >& operator<< (basic_ostream<char, char_traits<char> >&, const T&);
//which one is preferable when you ask for: cout << "literal";?
(ostream should be a typedef for basic_ostream<char, char_traits<char> >.)
The whole idea of making your overload a template is questionable, seeing that the overload clearly cannot handle any other class than your Record.
There probably are techniques to allow you to provide a single templated overload for a number of unrelated Record-like classes with a little template metaprogramming (enable_if and traits), if that is the idea.
I want to make a class based on "ostream" that does some auto-formatting to generate comma- or tab-separated-value files. My idea was to override "operator<<" to have it insert a separator before each value (except at the beginning and end of a line), and also to quote strings before writing them. Within the overriding "operator<<" method, I wanted to call the method of the base class, but I can't get it to work right.
Here's an example (compiles with g++ 4.3.3):
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(T value)
{
ostream::operator<<('+');
ostream::operator<<(value);
ostream::operator<<('+');
return *this;
}
};
template<> MyStream& MyStream::operator<< <string>(string value)
{
ostream::operator<<('*');
ostream::write(value.c_str(), value.size()); // ostream::operator<<(value);
ostream::operator<<('*');
return *this;
}
int main()
{
MyStream mystr(cout);
mystr << 10;
cout << endl;
mystr << "foo";
cout << endl;
mystr << string("test");
cout << endl;
return 0;
}
The two "operator<<" methods (template and specialization) are there to handle strings differently than everything else. But:
The characters ('+'/'*') are printed as numbers and not characters.
The C-String "foo" prints as a memory address (I think).
If the "write" line is exchanged with the commented part, the compiler complains that there's "no matching function for call to 'MyStream::operator<<(std::string&)'", even though I thought I was explicitly calling the base class method.
What am I doing wrong? Any help greatly appreciated.
The operator<< overloads that prints strings and characters are free functions. But as you force calling member functions, you will force them to convert to one candidate of the member functions declared in ostream. For '*', it will probably use the int overload, and for "foo", it will probably use the const void* overload.
I would not inherit ostream, but instead store the ostream as a reference member, and then delegate from your operator<< to it. I would also not make operator<< a member, but rather a free function template, and not specialize but overload the operator<< for both std::string and char const*.
Something like the following might work:
include
#include <ostream>
#include <string>
using namespace std;
class MyStream: public ostream
{
public:
MyStream(ostream& out): ostream(out.rdbuf()) {}
template <typename T> MyStream& operator<<(const T& value)
{
(ostream&)*this << '+' << value << '+';
return *this;
}
MyStream& operator<< (const string& value)
{
(ostream&)*this << '*' << value << '*';
return *this;
}
MyStream& operator<< (const char* cstr)
{
(ostream&)*this << '(' << cstr << ')';
return *this;
}
};
I overloaded operator <<
template <Typename T>
UIStream& operator<<(const T);
UIStream my_stream;
my_stream << 10 << " heads";
Works but:
my_stream << endl;
Gives compilation error:
error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'UIStream' (or there is no acceptable conversion)
What is the work around for making my_stream << endl work?
std::endl is a function and std::cout utilizes it by implementing operator<< to take a function pointer with the same signature as std::endl.
In there, it calls the function, and forwards the return value.
Here is a code example:
#include <iostream>
struct MyStream
{
template <typename T>
MyStream& operator<<(const T& x)
{
std::cout << x;
return *this;
}
// function that takes a custom stream, and returns it
typedef MyStream& (*MyStreamManipulator)(MyStream&);
// take in a function with the custom signature
MyStream& operator<<(MyStreamManipulator manip)
{
// call the function, and return it's value
return manip(*this);
}
// define the custom endl for this stream.
// note how it matches the `MyStreamManipulator`
// function signature
static MyStream& endl(MyStream& stream)
{
// print a new line
std::cout << std::endl;
// do other stuff with the stream
// std::cout, for example, will flush the stream
stream << "Called MyStream::endl!" << std::endl;
return stream;
}
// this is the type of std::cout
typedef std::basic_ostream<char, std::char_traits<char> > CoutType;
// this is the function signature of std::endl
typedef CoutType& (*StandardEndLine)(CoutType&);
// define an operator<< to take in std::endl
MyStream& operator<<(StandardEndLine manip)
{
// call the function, but we cannot return it's value
manip(std::cout);
return *this;
}
};
int main(void)
{
MyStream stream;
stream << 10 << " faces.";
stream << MyStream::endl;
stream << std::endl;
return 0;
}
Hopefully this gives you a better idea of how these things work.
The problem is that std::endl is a function template, as your operator <<
is. So when you write:
my_stream << endl;
you'll like the compiler to deduce the template parameters for the operator
as well as for endl. This isn't possible.
So you have to write additional, non template, overloads of operator << to
work with manipulators. Their prototype will look like:
UIStream& operator<<(UIStream& os, std::ostream& (*pf)(std::ostream&));
(there are two others, replacing std::ostream by std::basic_ios<char> and
std::ios_base, which you have also to provide if you want to allow all
manipulators) and their implementation will be very similar to the one of
your templates. In fact, so similar that you can use your template for
implementation like this:
typedef std::ostream& (*ostream_manipulator)(std::ostream&);
UIStream& operator<<(UIStream& os, ostream_manipulator pf)
{
return operator<< <ostream_manipulator> (os, pf);
}
A final note, often writing a custom streambuf is often a better way to
achieve what one try to achieve applying to technique you are using.
I did this to solve my problem, here is part of my code:
template<typename T>
CFileLogger &operator <<(const T value)
{
(*this).logFile << value;
return *this;
}
CFileLogger &operator <<(std::ostream& (*os)(std::ostream&))
{
(*this).logFile << os;
return *this;
}
Main.cpp
int main(){
CFileLogger log();
log << "[WARNINGS] " << 10 << std::endl;
log << "[ERRORS] " << 2 << std::endl;
...
}
I got the reference in here http://www.cplusplus.com/forum/general/49590/
Hope this can help someone.
See here for better ways of extending IOStreams. (A bit outdated, and tailored for VC 6, so you will have to take it with a grain of salt)
The point is that to make functors work (and endl, which both outputs "\n" and flushes is a functor) you need to implement the full ostream interface.
The std streams are not designed to be subclassed as they have no virtual methods so I don't think you'll get too far with that. You can try aggregating a std::ostream to do the work though.
To make endl work you need to implement a version of operator<< that takes a pointer-to-function as that is how the manipulators such as endl are handled i.e.
UStream& operator<<( UStream&, UStream& (*f)( UStream& ) );
or
UStream& UStream::operator<<( UStream& (*f)( UStream& ) );
Now std::endl is a function that takes and returns a reference to a std::basic_ostream so that won't work directly with your stream so you'll need to make your own version which calls through to the std::endl version in your aggregated std::iostream.
Edit: Looks likes GMan's answer is better. He gets std::endl working too!
In addition to the accepted answer, with C++11 it is possible to overload operator<< for the type:
decltype(std::endl<char, std::char_traits<char>>)