I was reading about nullptr
and doing workout on g++ and also on VS2010.
When I did
#include
using namespace std;
aut
The pointer literal is the keyword nullptr. It is a prvalue of type std::nullptr_t.
Type nullptr_t should be convertible to T*
, but compiler has no operator <<
for nullptr_t
and don't know to which type you want to convert nullptr
.
You can use this
cout << static_cast<void*>(nullptr) << endl;
This is because nullptr
is of type std::nullptr_t
, which does not define the appropriate operators for std::cout
to be able print objects of that type. You can define the operator yourself like this:
//std::cout is of type std::ostream, and nullptr is of type std::nullptr_t
std::ostream& operator << (std::ostream& os, std::nullptr_t ptr)
{
return os << "nullptr"; //whatever you want nullptr to show up as in the console
}
After this function is defined, it will be used to handle all attempts to print nullptr
via an ostream
. This way you don't need to cast nullptr
every time you print it.
I ran into this problem while I was writing some type-parameterized test code (using templates). I needed to print a value of type T
, where nullptr_t
was a valid type for T
. I came up with a solution where the value to be printed was wrapped inside a printable
template function. This function then makes use of template specialization to provide the desired behavior when a nullptr_t
is used.
#include <cstddef>
#include <iostream>
template <typename T> struct Printable
{
Printable(const T& val) : val(val) {}
void print(std::ostream& out) const {out << val;}
const T& val;
};
template <> struct Printable<std::nullptr_t>
{
Printable(nullptr_t) {}
void print(std::ostream& out) const {out << "null";}
};
template <typename T>
Printable<T> printable(const T& value) {return Printable<T>(value);}
template <typename T>
std::ostream& operator<<(std::ostream& out, const Printable<T>& p)
{
p.print(out);
return out;
}
int main() {
std::cout << printable(42) << " " << printable(nullptr) << "\n";
return 0;
}
Ideone link