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.
Related
I have a traditional C lib and a function (setsockopts) wants an argument by pointer. In C++11 (gcc 4.8), can I pass this argument without initializing a named variable?
I have the following, non-satisfying solution:
#include <iostream>
#include <memory>
int deref(int const * p) {return * p;}
using namespace std;
int main() {
int arg = 0; cout << deref(& arg) << endl;
// works, but is ugly (unnecessary identifier)
cout << deref(& 42) << endl;
// error: lvalue required as unary ‘&’ operand
cout << deref(& * unique_ptr<int>(new int(42))) << endl;
// works, but looks ugly and allocates on heap
}
I'd just create a wrapper to setsockopt if that's really a trouble (not tested)
template <typename T>
int setsockopt(int socket, int level, int optname, const T& value) {
return setsockopt(socket, level, optname, &value, sizeof(value));
}
...
setsockopt(socket, IPPROTO_TCP, TCP_NODELAY, 1);
Write a function template to convert rvalues to lvalues:
template<typename T>
T &as_lvalue(T &&val) {
return val;
}
Now, use it:
deref(&as_lvalue(42));
Warning: this doesn't extend the lifetime of the temporary, so you mustn't use the returned reference after the end of the full-expression in which the temporary was created.
You can bind a const reference to a temporary:
cout << deref(addressof<const int>(42)) << endl;
I'd like to know how do stream classes work in C++. When you say:
cout<<"Hello\n";
What does exactly do "<<". I know that cout is an object form iostream that represents the standard output stream oriented to narrow characters (char).
In C "<<" is the bitwise shift operator so it moves bits to the left but in C++ it's and insertion operator. Well, that's all I know, I don't really understand how does this work under the hood.
What I'm asking for is detailed explanation about stream classes in C++, how they are defined and implemented.
Thank you very much for your time and sorry for my English.
Let's create a class that looks like cout (but without as many bells and whistles).
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
int main() {
os_t os;
os << "hello\n";
os << "chaining " << "works too." << "\n";
}
Notes:
operator<< is an operator overload just like operator+ or all of the other operators.
Chaining works because we return ourselves: return *this;.
What if you can't change the os_t class because someone else wrote it?
We don't have to use member functions to define this functionality. We can also use free functions. Let's show that as well:
#include <string>
class os_t {
public:
os_t & operator<<(std::string const & s) {
printf("%s", s.c_str());
return *this;
}
};
os_t & operator<<(os_t & os, int x) {
printf("%d", x);
return os;
// We could also have used the class's functionality to do this:
// os << std::to_string(x);
// return os;
}
int main() {
os_t os;
os << "now we can also print integers: " << 3 << "\n";
}
Where else is operator overloading useful?
A great example of how this kind of logic is useful can be found in the GMP library. This library is designed to allow arbitrarily large integers. We do this, by using a custom class. Here's an example of it's use. Note that operator overloading let's us write code that looks almost identical to if we were using the traditional int type.
#include <iostream>
#include <gmpxx.h>
int main() {
mpz_class x("7612058254738945");
mpz_class y("9263591128439081");
x = x + y * y;
y = x << 2;
std::cout << x + y << std::endl;
}
<< is a binary operator in C++, and thus can be overloaded.
You know of the C usage of this operator, where 1 << 3 is a binary operation returning 8. You could think of this as the method int operator<<(int, int) where passing in arguments 1 and 3 returns 8.
Technically, operator<< could do anything. It's just an arbitrary method call.
By convention in C++, the << operator is used for handling streams in addition to being the bit-shift operator. When you perform cout << "Hello!", you are calling a method with prototype ostream & operator<< (ostream & output, char const * stream_me). Note the return value ostream &. That return allows you to call the method multiple times, like std::cout << "Hello World" << "!"; which is calling operator<< twice... once on std::cout and "Hello World", and the second time on the result of that first invocation and "!".
In general, if you were to create a class named class Foo, and you wanted it to be printable, you could define your printing method as ostream & operator<< (ostream & output, Foo const & print_me). Here is a simple example.
#include <iostream>
struct Circle {
float x, y;
float radius;
};
std::ostream & operator<< (std::ostream & output, Circle const & print_me) {
output << "A circle at (" << print_me.x << ", " << print_me.y << ") with radius " << print_me.radius << ".";
}
int main (void) {
Circle my_circle;
my_circle.x = 5;
my_circle.y = 10;
my_circle.radius = 20;
std::cout << my_circle << '\n';
return 0;
}
Operators can be considered functions with syntactic sugar that allow for clean syntax. This is simply a case of operator overloading.
I am developing a logger class that overloads the stream insertion operator.
I am having trouble catching the std::flush manipulator.
First, a quick summary of what I do:
Given an object of LogClass, I want to do the following:
LogClass logger;
logger << "Some text" << std::flush;
... and catch the std::flush manipulator.
All input is sent directly to an internal string stream for later logging by the following inlined operator (which works fine):
class LogClass
{
// ...
std::ostringstream m_internalStream;
template <typename T>
LogClass & operator<<(const T & rhs)
{
m_internalStream << rhs;
return *this;
}
// ...
};
I am trying to catch the std::flush manipulator by overloading as follows (which also works fine):
LogClass & LogClass::operator<<(std::ostream & (*manip)(std::ostream &))
{
std::ostream & (* const flushFunc)(std::ostream &) = std::flush;
// Is the supplied manipulator the same as std::flush?
if ((manip == flushFunc)) {
flush(); // <-- member function of LogClass
} else {
manip(m_stream);
}
return *this;
}
The problem shows if I try to make the local variable flushFunc static, as follows:
static std::ostream & (* const flushFunc)(std::ostream &) = std::flush;
In this case, the value of the incoming manip pointer is not equal to flushFunc.
Why is that? Does it have anything to do with template instantiations of the std::flush function for char?
I am using MS Visual Studio 2010 Pro.
The problem also shows in this small working code snippet:
#include <iostream>
#include <iomanip>
int main(int, char **)
{
static std::ostream & (* const staticFlushPtr)(std::ostream &) = std::flush;
std::ostream & (* const stackFlushPtr)(std::ostream &) = std::flush;
std::cout << std::hex <<
"staticFlushPtr: " << (void *) staticFlushPtr << "\n"
"stackFlushPtr: " << (void *) stackFlushPtr << "\n";
return 0;
}
... which gives this output on my machine:
staticFlushPtr: 013F1078
stackFlushPtr: 0FF10B30
Any ideas?
Best regards,
Rein A. Apeland
This looks like a definite bug in the compiler. If there were
DLLs or such involved, I could understand it, or at least make
excuses, but in such a trivial example as your main... (g++
gets it right.)
About all I can suggest is that you insert a filtering streambuf
in your output, which catches calls to sync.
Is it possible to write a method that takes a stringstream and have it look something like this,
void method(string str)
void printStringStream( StringStream& ss)
{
method(ss.str());
}
And can be called like this
stringstream var;
printStringStream( var << "Text" << intVar << "More text"<<floatvar);
I looked up the << operator and it looks like it returns a ostream& object but I'm probably reading this wrong or just not implementing it right.
Really all I want is a clean way to concatenate stuff together as a string and pass it to a function. The cleanest thing I could find was a stringstream object but that still leaves much to be desired.
Notes:
I can't use much of c++11 answers because I'm running on Visual Studio 2010 (against my will, but still)
I have access to Boost so go nuts with that.
I wouldn't be against a custom method as long as it cleans up this mess.
Edit:
With #Mooing Duck's answer mixed with #PiotrNycz syntax I achieved my goal of written code like this,
try{
//code
}catch(exception e)
{
printStringStream( stringstream() << "An exception has occurred.\n"
<<" Error: " << e.message
<<"\n If this persists please contact "<< contactInfo
<<"\n Sorry for the inconvenience");
}
This is as clean and readable as I could have hoped for.
Hopefully this helps others clean up writing messages.
Ah, took me a minute. Since operator<< is a free function overloaded for all ostream types, it doesn't return a std::stringstream, it returns a std::ostream like you say.
void printStringStream(std::ostream& ss)
Now clearly, general ostreams don't have a .str() member, but they do have a magic way to copy one entire stream to another:
std::cout << ss.rdbuf();
Here's a link to the full code showing that it compiles and runs fine http://ideone.com/DgL5V
EDIT
If you really need a string in the function, I can think of a few solutions:
First, do the streaming seperately:
stringstream var;
var << "Text" << intVar << "More text"<<floatvar;
printStringStream(var);
Second: copy the stream to a string (possible performance issue)
void printStringStream( ostream& t)
{
std::stringstream ss;
ss << t.rdbuf();
method(ss.str());
}
Third: make the other function take a stream too
Make your wrapper over std::stringstream. In this new class you can define whatever operator << you need:
class SSB {
public:
operator std::stringstream& () { return ss; }
template <class T>
SSB& operator << (const T& v) { ss << v; return *this; }
template <class T>
SSB& operator << (const T* v) { ss << v; return *this; }
SSB& operator << (std::ostream& (*v)(std::ostream&)) { ss << v; return *this; }
// Be aware - I am not sure I cover all <<'s
private:
std::stringstream ss;
};
void print(std::stringstream& ss)
{
std::cout << ss.str() << std::endl;
}
int main() {
SSB ssb;
print (ssb << "Hello" << " world in " << 2012 << std::endl);
print (SSB() << "Hello" << " world in " << 2012 << std::endl);
}
For ease of writing objects that can be inserted into a stream, all these classes overload operator<< on ostream&. (Operator overloading can be used by subclasses, if no closer match exists.) These operator<< overloads all return ostream&.
What you can do is make the function take an ostream& and dynamic_cast<> it to stringstream&. If the wrong type is passed in, bad_cast is thrown.
void printStringStream(ostream& os) {
stringstream &ss = dynamic_cast<stringstream&>(os);
cout << ss.str();
}
Note: static_cast<> can be used, it will be faster, but not so bug proof in the case you passed something that is not a stringstream.
Since you know you've got a stringstream, just cast the return value:
stringstream var;
printStringStream(static_cast<stringstream&>(var << whatever));
Just to add to the mix: Personally, I would create a stream which calls whatever function I need to call upon destruction:
#include <sstream>
#include <iostream>
void someFunction(std::string const& value)
{
std::cout << "someFunction(" << value << ")\n";
}
void method(std::string const& value)
{
std::cout << "method(" << value << ")\n";
}
class FunctionStream
: private virtual std::stringbuf
, public std::ostream
{
public:
FunctionStream()
: std::ostream(this)
, d_function(&method)
{
}
FunctionStream(void (*function)(std::string const&))
: std::ostream(this)
, d_function(function)
{
}
~FunctionStream()
{
this->d_function(this->str());
}
private:
void (*d_function)(std::string const&);
};
int main(int ac, char* av[])
{
FunctionStream() << "Hello, world: " << ac;
FunctionStream(&someFunction) << "Goodbye, world: " << ac;
}
It is worth noting that the first object sent to the temporary has to be of a specific set of types, namely one of those, the class std::ostream knows about: Normally, the shift operator takes an std::ostream& as first argument but a temporary cannot be bound to this type. However, there are a number of member operators which, being a member, don't need to bind to a reference! If you want to use a user defined type first, you need to extract a reference temporary which can be done by using one of the member input operators.
#include <string>
#include <iostream>
template <typename T>
T max(T a, T b) {
return a > b ? a : b;
}
class Dummy {
private:
std::string name;
int age;
public:
Dummy(int an_age) {age = an_age;}
bool operator> (Dummy &a) {return age > a.age;}
std::string toString() const {return "The age is " + age;}
};
std::ostream& operator<<(std::ostream& out, const Dummy& d) {return out<< d.toString();}
int main()
{
std::cout << max(3, 7) << std::endl;
std::cout << max(3.0, 7.0) << std::endl;
std::cout << max<int>(3, 7.0) << std::endl;
std::cout << max("hello", "hi") << std::endl;
Dummy d1(10);
Dummy d2(20);
std::cout << max(&d1, &d2) << std::endl;
return 0;
}
I'm pretty new to C++ but not new to programming. I've written the code to play with template and operator overloading in C++.
It took quite a while to make it compile and partially work.
The ostream operator<< is not working properly, only to return the address of the object. I can't figure out the causes.
I managed to make it compile by blind trial and error, so I suspect the code might be broken to some extent. And I may not be aware of what'd be improved.
Your max(&d1,&d2) expression gives you the address, and that is printed out. Your operator overloading is fine.
I assume the line you're talking about is
std::cout << max(&d1, &d2) << std::endl;
The problem is you are passing Dummy * instead of Dummy. That makes max return Dummy *, and since your overloaded operator<< takes (essentially) Dummy, it isn't invoked. If you're trying to pass by reference, you don't need to do anything special on the caller side, just make the function take a reference and the compiler will figure it out.
Don't write your own max, use the standard one instead:
#include <algorithm>
void f() { int a = std::max(8, 4); }
The only difference is that the standard max uses operator < by default, just like everything else in the standard library.
Your toString function does something different from what you think it does. It instead returns the sub string of "The age is " starting at the character number age. For example if age is 3, toString will return " age is ". To convert the integer to string you have to use ostringstream:
std::string toString() const {
std::ostringstream s;
s << "The age is " << age;
return s.str();
}