Why i still have ERROR: exepected an identifier in std::ofstream << val on the line below? msvc.
std::ostream& operator<< (bool val) { m_lock.lock(); std::ofstream << val; m_lock.unlock(); return *this; }
class OfstreamLog : public std::ofstream {
private:
std::mutex m_lock;
public:
OfstreamLog() : std::ofstream() { }
explicit OfstreamLog(const char* filename, ios_base::openmode mode = ios_base::out) : std::ofstream(filename, mode) { }
std::ostream& operator<< (bool val) { m_lock.lock(); std::ofstream << val; m_lock.unlock(); return *this; }
std::ostream& operator<< (short val);
std::ostream& operator<< (unsigned short val);
std::ostream& operator<< (int val);
std::ostream& operator<< (unsigned int val);
std::ostream& operator<< (long val);
std::ostream& operator<< (unsigned long val);
std::ostream& operator<< (float val);
std::ostream& operator<< (double val);
std::ostream& operator<< (long double val);
std::ostream& operator<< (void* val);
std::ostream& operator<< (std::streambuf* sb);
std::ostream& operator<< (std::ostream& (*pf)(std::ostream&));
std::ostream& operator<< (std::ios& (*pf)(std::ios&));
std::ostream& operator<< (ios_base& (*pf)(ios_base&));
};
std::ofstream is a type name. You can't call a nonstatic method or operator for it without any object.
In this case you probably want std::ofstream::operator<<(val); instead of std::ofstream << val;.
Explanation:
When you want to call method of a parent class from method of a child class, you do it like this:
class A
{
void func() {}
};
class B
{
void test()
{
func(); // Like this
}
};
But if child class have method with same name (more precisely, with same signature (it means, same name and argument types)), it will be called instead of parent's one. To explicitly call the method of the parent class, you can use this syntax:
class A {...};
class B
{
void test()
{
A::func(); // Notice `A::`
}
};
Now let's talk about operators. When you want to call an operator, you usually use an object name for it, like object << 10;. But when you want to call operator of a class (or it's parent) from a method of this class, you should use full operator syntax:
class A
{
operator<<(int){}
};
class B
{
void test()
{
operator<<(10); // <-----
*this << 10; // Also you can do it like this
}
};
Now, we combine these two techniques:
If child class have operator with same signature as parent's one and you want to call operator of the parent, you do it like this:
class A {...};
class B
{
void test()
{
A::operator<<(10); // Notice `A::`
*(A*)this << 10; // Also you can do it like this
}
};
Related
I would like to print a std::unique_ptr which is a class member of Bar.
However, the following code does not work see my comment on stream << bar.foo_unique();
I think I should change my foo_unique() accessor but I don't know how.
#include <iostream>
#include <memory>
class Foo
{
public:
Foo() : n_(1) {}
int n() const { return n_; }
private:
int n_;
};
std::ostream& operator<< (std::ostream& stream, const Foo& foo);
std::ostream& operator<< (std::ostream& stream, const Foo& foo)
{
stream << foo.n();
return stream;
}
class Bar
{
public:
Bar() : m_(2), foo_(), foo_unique_(std::make_unique<Foo>()) {}
int m() const { return m_; }
const Foo& foo() const { return foo_; }
const std::unique_ptr<Foo>& foo_unique() const { return foo_unique_; } // what to return here ?
private:
int m_;
Foo foo_;
std::unique_ptr<Foo> foo_unique_;
};
std::ostream& operator<< (std::ostream& stream, const Bar& bar);
std::ostream& operator<< (std::ostream& stream, const Bar& bar)
{
stream << bar.m() << ",";
stream << bar.foo();
// stream << bar.foo_unique(); // does not work !!!
return stream;
}
int main()
{
Bar bar;
std::cout << bar << std::endl;
}
How can I do that properly ?
edit : I want stream << bar.foo_unique(); to have the same behaviour as stream << bar.foo();
There is no output operator defined for std::unique_ptr<T>: it is a bit sad but many of the C++ classes are lacking output operators. The easiest approach is to just print the pointer:
stream << bar.foo_unique().get();
if you want to get the actually pointer printed or you'd dereference the pointer
stream << *bar.foo_unique();
if you want to get the pointee printed.
To use the output operator you can create your own output operator taking a std::unique_ptr<Foo> assuming Foo is a user-defined type. You'd put it into the same namespace as where Foo is defined:
std::ostream& operator<< (std::ostream& out, std::unique_ptr<Foo> const& foo) {
return out << *foo; // or foo.get()depending on what you want to get printed
}
There is no implicit conversion from std::unique_ptr<T> to T const& which is preventing the stream insertion operator from being determined. You have a couple of options here though. The first option is to provide one override of operator<< for std::unique_ptr<T> and one for T&. This can get tedious if you have use both std::unique_ptr and non-owning raw pointers or references. The second option is to provide a single templated version of operator<< to handle instances of std::unique_ptr<T> and then individual ones to handle T const&. Below is an example of how to accomplish this.
std::ostream& operator<< (std::ostream& out, Foo const& arg)
{
// output stuff here
return out;
}
template<class T>
std::ostream& operator<< (std::ostream& out, std::unique_ptr<T> const& arg)
{
return out << *arg;
}
Hello dear StackOverflowers!
I am having trouble with a template structure which comprises another (but non-template) structure.
Here's the thing:
Structure B is non-template and is defined inside a template structure A.
Strcure B is "protected" because it exists only for the purposes of structure A and no-one and nothing else shall use it outside of structure A.
There's an overload of operator<< for structure B, so that objects of type B can be sent to the standard output "cout << B_type_object;" (and it's A's friend so that it can access B which is protected).
The aforementioned printing of B objects is done only by methods defined in A (because of "2.").
As long as both structures are non-template everything works like a charm.
The moment A is a template I get an error message (provided in the code section).
Here is the working code (where A is not template):
#include <iostream>
#include <string>
struct A
{
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
friend std::ostream& operator<< (std::ostream& output, const typename A::B& ob);
public:
void method ()
{
B_object = "This is text.";
//No error here
std::cout << B_object;
}
};
std::ostream& operator<< (std::ostream& output, const typename A::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A obj;
obj.method();
return 0;
}
This is the code which doesn't work
#include <iostream>
#include <string>
template <typename T>
struct A
{
T variable;
protected:
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
};
B B_object;
template <typename X> friend std::ostream& operator<< (std::ostream& output, typename A/*<X>*/::B& ob);
public:
void method ()
{
B_object = "This is text.";
//ERROR: Invalid operands to binary expression ('ostream' (aka 'basic_ostream<char>') and 'A<int>::B')
std::cout << B_object;
}
};
template <typename X>
std::ostream& operator<< (std::ostream& output, typename A<X>::B& ob)
{
output << ob.something;
return output;
}
int main(int argc, const char * argv[])
{
A<int> obj;
obj.method();
return 0;
}
Just declare the operator inline in B, then it works:
...
struct B
{
std::string something;
B& operator= (const std::string&& rhs)
{
this->something = std::move(rhs);
return *this;
}
friend std::ostream& operator<< (std::ostream& output, const typename A<T>::B& ob)
{
output << ob.something;
return output;
}
};
...
This has also the advantage that your are not friending any operator<< of any A<X>. In your example, the operator taking A<string>::B would also be a friend of A<int>::B. For a more in-depth explanation, see this answer:
https://stackoverflow.com/a/4661372/36565
This is what I tried so far:
class Fahrzeug
{
public:
std::string Id() const;
void Id(const std::string &id);
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << Id();
return out;
}
private:
struct DatenImpl;
boost::scoped_ptr<DatenImpl> _datenImpl;
};
This yields a compiler error:
error C2352: Id() - illegal call of non-static member function
How can I implement the ostream operator<< for a "pimpled" class?
Your definition should be:
friend std::ostream& operator<< (std::ostream &out, const Fahrzeug &fzg)
{
out << fzg.Id(); // <--- qualify call to Id()
return out;
}
The operator is not a class member, although defined inside the class.
I have a slight problem where my << operator is not being called correctly.
This is what I have:
class SomeInterface
{
friend std::ostream& operator<<(std::ostream& str, const SomeInterface& data);
protected:
virtual void print(ostream& str) const = 0;
};
inline std::ostream& operator<< (std::ostream& o, SomeInterface const& b)
{
b.print(o);
return o;
}
}
Calling code looks something like:
SomeInterface* one = new someConcrete ();
cout << one;
The << overloaded function I was hoping would get called on the interface is not, let alone dispatching through to the derived class.
Try:
cout << *one;
Your code is asking to print the pointer, while your operator<< takes a const SomeInterface& reference.
You are calling std::ostream& operator<< (std::ostream& o, void*);, because the type of one is a pointer.
Try:
cout << *one;
This will call the overload that takes a (reference to) the actual object, not the pointer itself
Given a class such as:
class Person
{
private:
char *name;
public:
Person()
{
name = new char[20];
}
~Person()
{
delete [] name;
}
}
I want to print to print the name from an instance of this, using a statement like the following:
cout << myPerson << endl;
What do I need to do to define the << output operator for this class?
add this in the class:
friend std::ostream& operator<< (std::ostream& out, const Person& P);
and then define the operator<< something like this:
std::ostream& operator<< (std::ostream& out, const Person& P) {
out << P.name;
return out;
}
Define a member function print() that takes an ostream as an argument. Then let the overloaded operator<< call this member function. This way you can avoid using friend. Example:
void YourClass::print(ostream& out) const
{
//implement printing ...
}
ostream& operator<<(ostream& out, const YourClass& m)
{
m.print(out);
return out;
}