Why doesn't implicit conversion work with wide ostream? - c++

I have some behaviour that I do not understand. I observed this on VS2005, but IDEONE (using GCC 4.7.2) outputs basically the same.
Here's the code:
#include <iostream>
#include <string>
struct UserString {
const char* p;
operator const char*() const {
std::cout << "! " << __FUNCTION__ << std::endl;
return p;
}
UserString()
: p ("UserString")
{ }
};
struct WUserString {
const wchar_t* p;
operator const wchar_t*() const {
std::cout << "! " << __FUNCTION__ << std::endl;
return p;
}
WUserString()
: p (L"WUserString")
{ }
};
int main() {
using namespace std;
cout << "String Literal" << endl;
cout << string("std::string") << endl;
cout << UserString() << endl;
cout << static_cast<const char*>(UserString()) << endl;
wcout << L"WString Literal" << endl;
wcout << wstring(L"std::wstring") << endl;
wcout << WUserString() << endl;
wcout << static_cast<const wchar_t*>(WUserString()) << endl;
return 0;
}
Here's the output:
String Literal
std::string
! operator const char* **** "works"
UserString ****
! operator const char*
UserString
WString Literal
std::wstring
! operator const wchar_t* **** "doesn't" - op<<(void*) is used
0x80491b0 ****
! operator const wchar_t*
WUserString
What's going on here?!?

There is a partial specialization for basic_ostream
template<class _TraitsT>
basic_ostream<char, _TraitsT>&
operator<<(basic_ostream<char, _TraitsT>& _Stream, const char* _String);
which is a good fit for the cout << UserString() case.
There is nothing similar for wchar_t and WUserString(), so the member function
basic_ostream& operator<<(const void* _Address);
will be the best match for that (as in most "unusual" cases).

Related

non-helper << operator not working C++

I'm trying to overload the << operator for the display function call.
Heres my code:
#include <iostream>
#include <cstring>
using namespace std;
// global variable
const int MAX = 3;
// class definition
class CString{
char str[MAX+1];
public:
CString(char* param){
if(param == nullptr){
str[0] = '\0';
return;
}
strncpy(str,param,MAX);
str[MAX] = '\0';
}
void display(ostream& os){
os << str;
}
};
// << operator overloading
ostream& operator << (ostream& os, CString& cs){
static int call = 0;
os << call << ": ";
cs.display(os);
call++;
return os;
}
void process(char* parm){
CString cs(parm);
// here is where my issue is
cs.display(cout);
cout << endl;
}
//----------------------------------------------------------------
int main(int argc,char *argv[]){
cout << "Command Liine : ";
for(int arg = 0; arg < argc ; arg++){
cout << " " << argv[arg];
}
cout << endl;
if( argc == 1){
cout << "Insufffiecentnumber of arguemnts (min1)" << endl;
return 1;
}
cout << " Maxium numver of characters stored: " << MAX << endl;
for(int arg = 1; arg < argc; arg++){
process(argv[arg]);
}
return 0;
}
EDIT:
Here is the correct output and the output I have:
Correct:
Command Line : w1 oop345 btp305
Maximum number of characters stored : 3
0: oop
1: btp
Mine:
Command Line : w1 OOP345 DBS305
Maxium number of characters stored: 3
OOP
DBS
I'm having an issue with my << operator not working, I can't seem to figure it out. The ostream& operator<<(ostream& os, CString& cs) does not seem to be loading its syntax.
Question:
Does anyone know where my mistake has been made?
You wrote a correct overloading of << operator, but in method process() you used a public method display() of class CString instead of using << operator directly.
Just change one line in method process():
cs.display(cout); to: cout << cs;
void process(char* parm){
CString cs(parm);
// here is where my issue is
cout << cs;
cout << endl;
}
P.S. you do not need method CString::display at all as you already overload << operator for this class.

How to format text using std:out setfill std::setw std:right with one padding space

I just want to format a string and an integer value with right justify.
There is no problem to do this without leading space before the integer value.
bytes.....................123981
total bytes..............1030131
But it should look like this:
bytes ................... 123981
total bytes ............ 1030131
Unfortunately the example below wont work, because setw (right justify) relates only to the next stream element.
int iBytes = 123981;
int iTotalBytes = 1030131;
cout << setfill('.');
cout << right;
cout << "bytes " << setw(20) << " " << iBytes << endl;
cout << "total bytes " << setw(14) << " " << iTotalBytes << endl;
I hardly ever use std::cout, so is there a simple way to do this without previously joining a space char to the value?
The simplest way would be to write your " " and value into a std::stringstream and write the resulting str() into your output stream like:
std::stringstream ss;
ss << " " << iBytes;
cout << "bytes " << setw(20) << ss.str() << endl;
And here comes the complete overkill. A templated class prefixed which can be printed and bundles the two constructor arguments prefix,val into one string to be printed. number format, and precision is taken from the final output stream. Works with ints,floats, strings and const char *. And should work with every arg that has a valid output operator.
#include <fstream>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
template<class T>
class prefixed_base {
public:
prefixed_base(const std::string & prefix,const T val) : _p(prefix),_t(val) {
}
protected:
std::string _p;
T _t;
};
// Specialization for const char *
template<>
class prefixed_base<const char*> {
public:
prefixed_base(const std::string & prefix,const char * val) : _p(prefix),_t(val) {
}
protected:
std::string _p;
std::string _t;
};
template<class T>
class prefixed : public prefixed_base<T> {
private:
typedef prefixed_base<T> super;
public:
prefixed(const std::string & prefix,const T val) : super(prefix,val) {
}
// Output the prefixed value to an ostream
// Write into a stringstream and copy most of the
// formats from os.
std::ostream & operator()(std::ostream & os) const {
std::stringstream ss;
// We 'inherit' all formats from the
// target stream except with. This Way we
// keep informations like hex,dec,fixed,precision
ss.copyfmt(os);
ss << std::setw(0);
ss << super::_p;
ss.copyfmt(os);
ss << std::setw(0);
ss << super::_t;
return os << ss.str();
}
};
// Output operator for class prefixed
template<class T>
std::ostream & operator<<(std::ostream & os,const prefixed<T> & p) {
return p(os);
}
// This function can be used directly for output like os << with_prefix(" ",33.3)
template<class T>
prefixed<T> with_prefix(const std::string & p,const T v) {
return prefixed<T>(p,v);
}
int main() {
int iBytes = 123981;
int iTotalBytes = 1030131;
cout << setfill('.');
cout << right;
cout << "bytes " << setw(20) << with_prefix(" ",iBytes) << endl;
cout << "total bytes " << setw(14) << with_prefix(" ",iTotalBytes) << endl;
cout << "bla#1 " << setw(20) << std::fixed << std::setprecision(9) << with_prefix(" ",220.55) << endl;
cout << "blablabla#2 " << setw(14) << std::hex << with_prefix(" ",iTotalBytes) << endl;
}
#Oncaphillis thx for the piece of source code, I adapt it a bit for my needs. I just wrote a function to convert values. std::to_string is used by C++11 standard, so I decided to use _to_string/_to_wstring instead. The tricky part was to get "wcout" to work with UNICODEs on Windows console. I didn’t really manage it, so I had to do a workaround. Anyway to print e.g. Cyrillic characters you have to change the console font to Consolas or Lucida.
#include <windows.h>
#include <tchar.h>
#include <iostream>
#include <iomanip>
#include <sstream>
using namespace std;
#if defined(UNICODE) || defined(_UNICODE)
#define _tcout std::wcout
#define _to_tstring _to_wstring
template <typename T>std::wstring _to_wstring(const T& value) {
std::wostringstream wos;
wos.copyfmt(std::wcout);
wos << value;
return wos.str();
}
#else
#define _tcout std::cout
#define _to_tstring _to_string
template <typename T> std::string _to_string(const T& value) {
std::ostringstream os;
os.copyfmt(std::cout);
os << value;
return os.str();
}
#endif
int _tmain(int argc, _TCHAR* argv[]) {
int iBytes = 123981;
int iTotalBytes = 1030131;
#if defined(UNICODE) || defined(_UNICODE)
wostringstream newCoutBuffer;
wstreambuf* oldCoutBuffer = _tcout.rdbuf(newCoutBuffer.rdbuf()); // redirect cout buffer
#endif
_tcout.imbue(std::locale("German")); // enable thousand separator
_tcout.precision(0);
_tcout << setfill(_T('.')) << right << fixed;
_tcout << _T("bytes ") << setw(20) << _T(" ") + _to_tstring(iBytes) << endl;
_tcout << _T("bytes total ") << setw(14) << _T(" ") + _to_tstring(iTotalBytes) << endl;
_tcout << _T("bla bla ") << fixed << setprecision(9); _tcout << setw(18) << _T(" ") + _to_tstring(0.1337) << endl;
_tcout << _T("Милые женщины ") << hex; _tcout << setw(12) << _T(" ") + _to_tstring(iTotalBytes) << endl;
_tcout << _T("retries ") << dec; _tcout << setw(18) << _T(" ") + _to_tstring(2) + _T(" of ") + _to_tstring(20) << endl;
#if defined(UNICODE) || defined(_UNICODE)
DWORD dwWritten;
WriteConsoleW(GetStdHandle(STD_OUTPUT_HANDLE), newCoutBuffer.str().c_str(),newCoutBuffer.tellp(),&dwWritten,NULL);
_tcout.rdbuf(oldCoutBuffer);
#endif
return 0;
}
Output:
bytes ............ 123.981
bytes total .... 1.030.131
bla bla ...... 0,133700000
Милые женщины ..... fb.7f3
retries .......... 2 of 20

c++ simple stream manipulation with ostream and istream?

I have been looking for a solution but couldn't find what I need/want.
All I want to do is pass a stream intended for std::cout to a function, which manipulates it. What I have used so far is a template function:
template<typename T>
void printUpdate(T a){
std::cout << "blabla" << a << std::flush;
}
int main( int argc, char** argv ){
std::stringstream str;
str << " hello " << 1 + 4 << " goodbye";
printUpdate<>( str.str() );
return 0;
}
What I would prefer is something like:
printUpdate << " hello " << 1 + 4 << " goodbye";
or
std::cout << printUpdate << " hello " << 1 + 4 << " goodbye";
I was trying to do:
void printUpdate(std::istream& a){
std::cout << "blabla" << a << std::flush;
}
but that gave me:
error: invalid operands of types ‘void(std::istream&) {aka void(std::basic_istream<char>&)}’ and ‘const char [5]’ to binary ‘operator<<’
You can't output data to an input stream, just not a good thing to do.
Change:
void printUpdate(std::istream& a){
std::cout << "blabla" << a << std::flush;
}
To:
void printUpdate(std::ostream& a){
std::cout << "blabla" << a << std::flush;
}
Note the stream type change.
Edit 1:
Also, you can't output a stream to another stream, at least std::cout.
The return value of << a is a type ostream.
The cout stream doesn't like being fed another stream.
Change to:
void printUpdate(std::ostream& a)
{
static const std::string text = "blabla";
std::cout << text << std::flush;
a << text << std::flush;
}
Edit 2:
You need to pass a stream to a function requiring a stream.
You can't pass a string to a function requiring a stream.
Try this:
void printUpdate(std::ostream& out, const std::string& text)
{
std::cout << text << std::flush;
out << text << std::flush;
}
int main(void)
{
std::ofstream my_file("test.txt");
printUpdate(my_file, "Apples fall from trees.\n");
return 0;
}
Chaining Output Streams
If you want to chain things to the output stream, like results from functions, the functions either have to return a printable (streamable object) or the same output stream.
Example:
std::ostream& Fred(std::ostream& out, const std::string text)
{
out << "--Fred-- " << text;
return out;
}
int main(void)
{
std::cout << "Hello " << Fred("World!\n");
return 0;
}

Using operator overloading in C++

class A
{
public:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
cout << string << endl;
}
};
main()
{
int temp1 = 5;
char str = 'c';
float p= 2.22;
A a;
(a<<temp1);
(a<<str);
(a<<p);
(a<<"value of p=" << 5);
}
I want the output to be: value of p=5
What changes should is do...and the function should accept all data type that is passed
There are 2 solutions.
First solution is to make it a template.
template <typename T>
ostream& operator<<(const T& input) const
{
cout << "In Overloaded function1\n";
return (cout << input << endl);
}
However, this will make the a << str and a << p print c and 2.22, which is different from your original code. that output 99 and 2.
The second solution is simply add an overloaded function for const char*:
ostream& operator<<(int string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
ostream& operator<<(const char* string)
{
cout << "In Overloaded function1\n";
return (cout << string << endl);
}
This allows C strings and everything convertible to int to be A <<'ed, but that's all — it won't "accept all data type that is passed".
BTW, you have forgotten to return the ostream.

container won't sort, test case included, (easy question?)

I can't see what I'm doing wrong. I think it might be one of the Rule of Three methods. Codepad link
#include <deque>
//#include <string>
//#include <utility>
//#include <cstdlib>
#include <cstring>
#include <iostream>
//#include <algorithm> // I use sort(), so why does this still compile when commented out?
#include <boost/filesystem.hpp>
#include <boost/foreach.hpp>
using namespace std;
namespace fs = boost::filesystem;
class Page
{
public:
// constructor
Page(const char* path, const char* data, int size) :
path_(fs::path(path)),
size_(size),
data_(new char[size])
{
// cout << "Creating Page..." << endl;
strncpy(data_, data, size);
// cout << "done creating Page..." << endl;
}
// copy constructor
Page(const Page& other) :
path_(fs::path(other.path())),
size_(other.size()),
data_(new char[other.size()])
{
// cout << "Copying Page..." << endl;
strncpy(data_, other.data(), size_);
// cout << "done copying Page..." << endl;
}
// destructor
~Page() { delete[] data_; }
// accessors
const fs::path& path() const { return path_; }
const char* data() const { return data_; }
int size() const { return size_; }
// operators
Page& operator = (const Page& other) {
if (this == &other)
return *this;
char* newImage = new char[other.size()];
strncpy(newImage, other.data(), other.size());
delete[] data_;
data_ = newImage;
return *this;
}
bool operator < (const Page& other) const { return path_ < other.path(); }
private:
fs::path path_;
int size_;
char* data_;
};
class Book
{
public:
Book(const char* path) :
path_(fs::path(path))
{
cout << "Creating Book..." << endl;
cout << "pushing back #1" << endl;
pages_.push_back(Page("image1.jpg", "firstImage", 10));
cout << "pushing back #3" << endl;
pages_.push_back(Page("image3.jpg", "thirdImage", 10));
cout << "pushing back #2" << endl;
pages_.push_back(Page("image2.jpg", "secondImage", 11));
cout << "testing operator <" << endl;
cout << pages_[0].path().string() << (pages_[0] < pages_[1]? " < " : " > ") << pages_[1].path().string() << endl;
cout << pages_[1].path().string() << (pages_[1] < pages_[2]? " < " : " > ") << pages_[2].path().string() << endl;
cout << pages_[0].path().string() << (pages_[0] < pages_[2]? " < " : " > ") << pages_[2].path().string() << endl;
cout << "sorting" << endl;
BOOST_FOREACH (Page p, pages_)
cout << p.path().string() << endl;
sort(pages_.begin(), pages_.end());
cout << "done sorting\n";
BOOST_FOREACH (Page p, pages_)
cout << p.path().string() << endl;
cout << "done Creating Book" << endl;
}
private:
deque<Page> pages_;
fs::path path_;
};
int main() {
Book* book = new Book("/some/path/");
}
I just kept messing around, and realized that my assignment operator needs to copy all the other parameters over as well, not just the heap allocated ones.
Man do I feel dumb. >_<
Btw followup question: Is there a way to do the sorting without needing to strncpy() all the buffers and just swap the pointer addresses around instead?
edit:
tnx dirkgently. Yeah that's what it was, sry didn't see your comment before I posted this.