I am feeling a bit confused about how to instantiate this template. I know it is gonna be easier to simply use friend membership to realize what I want, but what if I force to do in this way? I just wanna figure it out. (And btw, I know this template seems meaningless), I just want to make it compile.
#include <iostream>
template <typename T>
inline std::ostream& operator<< (std::ostream& os, const T& date)
{
os << date.getD() << " " << date.getM() << " " << date.getY() << "\n";
return os;
}
class Date
{
private:
int dd, mm, yy;
public:
Date(int d, int m, int y) : dd(d), mm(m), yy(y) {}
int getD() const;
int getM() const;
int getY() const;
};
int Date::getD() const { return dd; }
int Date::getM() const { return mm; }
int Date::getY() const { return yy; }
int main(int argc, char const *argv[])
{
Date dat(1, 2, 2003);
std::cout << <Date> dat;
return 0;
}
Two issues:
You're declaring operator<< as template that could accept any types; which would lead to ambiguity issue with std::operator<<.
You can't specify template argument explicitly when calling the operator in operator style. (You can do it in ugly function style like operator<< <Date>(std::cout, dat);) Actually you don't need to specify it, the template parameter could be deduced fine here.
You can change the code to
std::ostream& operator<< (std::ostream& os, const Date& date) {
os << date.getD() << " " << date.getM() << " " << date.getY() <<"\n";
return os;
}
then
Date dat(1,2,2003);
std::cout << dat;
LIVE
but what if I force to do in this way?
As others mentioned, you do not need a template here. But if you insist to do it by templates, you can apply SFINAE to the templated overload of operator<<.
(See live here)
#include <type_traits> // std::enable_if, std::is_same
template <typename T>
auto operator<< (std::ostream& os, const T& date)
-> std::enable_if_t<std::is_same_v<Date, T>, std::ostream&>
{
os << date.getD() << " " << date.getM() << " " << date.getY() << "\n";
return os;
}
This will be done automatically by the compiler. Simply do
int main(int argc, char const *argv[])
{
Date dat(1,2,2003);
std::cout << dat;
return 0;
}
This is done with ADL (Argument-dependent lookup).
Related
myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};
How can I pass this to operator<< in c++ class? Or am I just doing this wrong (likely).
For example, in the following class I just have a loop that repetitively asks for and prints an integer. However, cout<<this just prints the address of the instance, but I would like to use the defined operator overload.
#include<iostream>
using std::cout; using std::endl; using std::cin;
class C {
int n;
public:
C(int n) : n(n) {};
friend std::ostream& operator<<(std::ostream&, const C&);
void set_n(int i) { n = i; }
void play() {
int input;
while (true) {
cout << this;
cin >> input;
set_n(input);
}
}
};
std::ostream& operator<<(std::ostream& os, const C& c) {
cout << c.n << "\n";
return os;
}
int main(int argc, char *argv[]) {
C c = C(1);
c.play();
return 0;
}
this is a pointer. You need
cout << *this;
Also, your definition of operator<< should probably use the parameter os rather than always using cout.
this is a pointer. You probably need to dereference it.
cout << *this;
I have the following code...
#include <sstream>
enum class eTag
{
A,
B,
C
};
template<eTag I> std::ostream& operator<< (std::ostream& str, int i)
{
return str; // do nothing
}
template<> std::ostream& operator<< <eTag::A>(std::ostream& str, int i)
{
return str << "A:" << i; // specialize for eTag::A
}
template<> std::ostream& operator<< <eTag::B>(std::ostream& str, int i)
{
return str << "B:" << i; // specialize for eTag::B
}
template<> std::ostream& operator<< <eTag::C>(std::ostream& str, int i)
{
return str << "C:" << i; // specialize for eTag::C
}
int main()
{
std::ostringstream s;
// s << <eTag::A>(42) << std::endl;
return 0;
}
This compiles. But as you can see from the commented line in main(), I'm struggling with how to actually invoke a specialization of the ostream operator.
Quick answer:
operator<< <eTag::A>(std::cout,42);
I think you're much better off with implementing your own template-class manipulator that friends ostream& operator<<(ostream&), and keeps the state as a member variable (initialized via a constructor). See here (except for the template-part)
operator<<<eTag::A>(std::cout, 42) << std::endl;
(You can add a space between operator<< and the template argument list if you want. Doesn't make a difference.)
This is pretty nasty. Usually we don't write operators that require explicit template arguments. Better to do something like this:
inline std::ostream& operator<<(std::ostream& os, eTag x) {
if (x == eTag::A) {
return os << "A:";
} else if (x == eTag::B) {
return os << "B:";
} else if (x == eTag::C) {
return os << "C:";
} else {
throw std::range_error("Out of range value for eTag");
}
}
Then:
std::cout << eTag::A << 42 << std::endl;
A good compiler will be able to inline this, so your code will be as efficient as if you had just typed
std::cout << "A:" << 42 << std::endl;
myclass is a C++ class written by me and when I write:
myclass x;
cout << x;
How do I output 10 or 20.2, like an integer or a float value?
Typically by overloading operator<< for your class:
struct myclass {
int i;
};
std::ostream &operator<<(std::ostream &os, myclass const &m) {
return os << m.i;
}
int main() {
myclass x(10);
std::cout << x;
return 0;
}
You need to overload the << operator,
std::ostream& operator<<(std::ostream& os, const myclass& obj)
{
os << obj.somevalue;
return os;
}
Then when you do cout << x (where x is of type myclass in your case), it would output whatever you've told it to in the method. In the case of the example above it would be the x.somevalue member.
If the type of the member can't be added directly to an ostream, then you would need to overload the << operator for that type also, using the same method as above.
it's very easy, just implement :
std::ostream & operator<<(std::ostream & os, const myclass & foo)
{
os << foo.var;
return os;
}
You need to return a reference to os in order to chain the outpout (cout << foo << 42 << endl)
Even though other answer provide correct code, it is also recommended to use a hidden friend function to implement the operator<<. Hidden friend functions has a more limited scope, therefore results in a faster compilation. Since there is less overloads cluttering the namespace scope, the compiler has less lookup to do.
struct myclass {
int i;
friend auto operator<<(std::ostream& os, myclass const& m) -> std::ostream& {
return os << m.i;
}
};
int main() {
auto const x = myclass{10};
std::cout << x;
return 0;
}
Alternative:
struct myclass {
int i;
inline operator int() const
{
return i;
}
};
I want to write a function that outputs something to a ostream that's passed in, and return the stream, like this:
std::ostream& MyPrint(int val, std::ostream* out) {
*out << val;
return *out;
}
int main(int argc, char** argv){
std::cout << "Value: " << MyPrint(12, &std::cout) << std::endl;
return 0;
}
It would be convenient to print the value like this and embed the function call in the output operator chain, like I did in main().
It doesn't work, however, and prints this:
$ ./a.out
12Value: 0x6013a8
The desired output would be this:
Value: 12
How can I fix this? Do I have to define an operator<< instead?
UPDATE: Clarified what the desired output would be.
UPDATE2: Some people didn't understand why I would print a number like that, using a function instead of printing it directly. This is a simplified example, and in reality the function prints a complex object rather than an int.
You can't fix the function. Nothing in the spec requires a compiler to evaluate a function call in an expression in any particular order with respect to some unrelated operator in the same expression. So without changing the calling code, you can't make MyPrint() evaluate after std::cout << "Value: "
Left-to-right order is mandated for expressions consisting of multiple consecutive << operators, so that will work. The point of operator<< returning the stream is that when operators are chained, the LHS of each one is supplied by the evaluation of the operator to its left.
You can't achieve the same thing with free function calls because they don't have a LHS. MyPrint() returns an object equal to std::cout, and so does std::cout << "Value: ", so you're effectively doing std::cout << std::cout, which is printing that hex value.
Since the desired output is:
Value: 12
the "right" thing to do is indeed to override operator<<. This frequently means you need to either make it a friend, or do this:
class WhateverItIsYouReallyWantToPrint {
public:
void print(ostream &out) const {
// do whatever
}
};
ostream &operator<<(ostream &out, const WhateverItIsYouReallyWantToPrint &obj) {
obj.print(out);
}
If overriding operator<< for your class isn't appropriate, for example because there are multiple formats that you might want to print, and you want to write a different function for each one, then you should either give up on the idea of operator chaining and just call the function, or else write multiple classes that take your object as a constructor parameter, each with different operator overloads.
You want to make MyPrint a class with friend operator<<:
class MyPrint
{
public:
MyPrint(int val) : val_(val) {}
friend std::ostream& operator<<(std::ostream& os, const MyPrint& mp)
{
os << mp.val_;
return os;
}
private:
int val_;
};
int main(int argc, char** argv)
{
std::cout << "Value: " << MyPrint(12) << std::endl;
return 0;
}
This method requires you to insert the MyPrint object into the stream of your choice. If you REALLY need the ability to change which stream is active, you can do this:
class MyPrint
{
public:
MyPrint(int val, std::ostream& os) : val_(val), os_(os) {}
friend std::ostream& operator<<(std::ostream& dummy, const MyPrint& mp)
{
mp.os_ << mp.val_;
return os_;
}
private:
int val_;
std::ostream& os_
};
int main(int argc, char** argv)
{
std::cout << "Value: " << MyPrint(12, std::cout) << std::endl;
return 0;
}
You have two options. The first, using what you already have is:
std::cout << "Value: ";
MyPrint(12, &std::cout);
std::cout << std::endl;
The other, which is more C++-like, is to replace MyPrint() with the appropriate std::ostream& operator<<. There's already one for int, so I'll do one just a tad more complex:
#include <iostream>
struct X {
int y;
};
// I'm not bothering passing X as a reference, because it's a
// small object
std::ostream& operator<<(std::ostream& os, const X x)
{
return os << x.y;
}
int main()
{
X x;
x.y = 5;
std::cout << x << std::endl;
}
There's no way to do what you're expecting there because of the order the functions are evaluated in.
Is there any particular reason you need to write directly to the ostream like that? If not, just have MyPrint return a string. If you want to use a stream inside MyPrint to generate the output, just use a strstream and return the result.
First, there is no reason not to pass in the ostream by reference rather than by a pointer:
std::ostream& MyPrint(int val, std::ostream& out) {
out << val;
return out;
}
If you really don't want to use std::ostream& operator<<(std::ostream& os, TYPE), you can do this:
int main(int argc, char** argv){
std::cout << "Value: ";
MyPrint(12, std::cout) << std::endl;
return 0;
}
After changing the pointer to a reference, you can do this:
#include <iostream>
std::ostream& MyPrint(int val, std::ostream& out) {
out << val;
return out;
}
int main(int, char**) {
MyPrint(11, std::cout << "Value: ") << std::endl;
return 0;
}
The syntax for MyPrint is essentially that of an unrolled operator<< but with an extra argument.
In your case the answer is obviously:
std::cout << "Value: " << 12 << std::endl;
If that isn't good enough, please explain what output you want to see.