Trying to print vector of objects with overloading? - c++

I'm working on a hash table program involving linear probing. I'm trying to print out the vector of Symbol class objects but I'm running into two errors every time I try to do it. I've posted these errors below:
LinearProbing.h: In instantiation of 'void HashTable<HashedObj>::print() [with HashedObj = Symbol]':
Driver.cpp:79:21: required from here
LinearProbing.h:82:4: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
In file included from /opt/local/include/gcc47/c++/iostream:40:0,
from Driver.cpp:1:
/opt/local/include/gcc47/c++/ostream:600:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = HashTable<Symbol>::HashEntry]'
Here is where I'm trying to print the vector in the HashTable class...
class HashTable
{
///...
void print()
{
typename vector<HashEntry>::iterator vIter = array.begin;
while(vIter != array.end())
{
cout<< *vIter << "\n";
++vIter;
}
}
private:
vector<HashEntry> array;
};
And my overloading in the Symbol class...
friend ostream & operator <<(ostream & outstream, Symbol & symbol) //overloaded to print out the the HashTable
{
int num = symbol.type;
string name = symbol.data;
outstream << name << " : " << num << "\n";
return outstream;
}

Not sure what you're doing there but you have defined a vector of HashEntry and calling cout on HashEntry but your operator<< overload operates on Symbol instead.
The operator<< for class Symbol should look something like this
class Symbol {
private:
friend ostream& operator<<(ostream &os, const Symbol &s);
int type;
string data;
};
ostream& operator<<(ostream &os, const Symbol &s)
{
os << s.data << " : " << s.type;
return os;
}

Related

cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’

There have been a couple posts on this subject, but I think this is one of the simplest examples, and hopefully it will clarify some things about cout and initialization.
So this works:
class A {
public:
std::ostream& operator<< (std::ostream& os) {
return os;
}
};
class B {
std::ostream& operator<< (std::ostream& os) {
A a(); // <-- LOOK
std::cout << a;
return os;
}
};
But if I simply A a() to A a:
class A {
public:
std::ostream& operator<< (std::ostream& os) {
return os;
}
};
class B {
std::ostream& operator<< (std::ostream& os) {
A a; // <-- LOOK
std::cout << a;
return os;
}
};
It throws:
nvcc main.cpp util.cpp -o main -lcublas -std=c++11
In file included from main.cpp:9:0:
cout-test.hpp: In member function ‘std::ostream& B::operator<<(std::ostream&)’:
cout-test.hpp:21:20: error: cannot bind ‘std::ostream {aka std::basic_ostream<char>}’ lvalue to ‘std::basic_ostream<char>&&’
std::cout << a;
^
In file included from /usr/include/c++/4.8/iostream:39:0,
from main.cpp:5:
/usr/include/c++/4.8/ostream:602:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = A]’
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
make: *** [main] Error 1
I get the same error if I make A a a class member:
class B {
A a; // <-- LOOK
std::ostream& operator<< (std::ostream& os) {
std::cout << a;
return os;
}
};
What gives?
First Case
A a();
does not construct an object. It declares a function. This parsing problem is known as The Most Vexing Parse.
A a();
std::cout << a;
works because a is converted to a bool in this case. See Why does pointer to int convert to void* but pointer to function convert to bool? why that works.
Second Case
A a;
std::cout << a;
does not work because of the way you have defined the operator<< function. You'll have to use
A a;
a << std::cout;
The operator<< function needs to be a non-member function in order to use:
A a;
std::cout << a;
See my answer to another SO post to understand why.

Overloading << and >> for STL map: "cannot bind lvalue"

I am trying to save an STL map containing custom objects to a file, using fstream. I am doing this using << and >> operator overloading.
#include <iostream>
#include <string>
#include <map>
#include <fstream>
#define DELIM '/'
struct Point{
public:
int x, y;
};
//operator overloads for point
std::istream& operator>>(std::istream& is, Point& p){
std::string input;
std::getline(is, input, DELIM);
p.x = std::stoi(input);
std::getline(is, input, DELIM);
p.y = std::stoi(input);
return is;
}
std::ostream& operator<<(std::ostream& os, Point& p){
os << p.x << DELIM << p.y << DELIM;
return os;
}
//operator overloads for map<string, point>
std::istream& operator>>(std::istream& is, std::map<std::string, Point>& m){
std::string input;
std::getline(is, input, DELIM);
int map_size = std::stoi(input);
for(int i = 0; i < map_size; i++){
std::getline(is, input, DELIM);
Point p; is >> p;
m[input] = p;
}
return is;
}
std::ostream& operator<<(std::ostream& os, std::map<std::string, Point>& m){
os << m.size() << DELIM;
for(const auto& pair : m){
os << pair.first << DELIM;
os << pair.second;
}
return os;
}
int main(){
Point p1;
p1.x = 1; p1.y = 2;
Point p2;
p2.x = 100; p2.y = 150;
std::map<std::string, Point> map;
map["p1"] = p1;
map["p2"] = p2;
return 0;
}
When I try to compile this file I get the following error:
test.cpp: In function 'std::ostream& operator<<(std::ostream&, std::map<std::basic_string<char>, Point>&)':
test.cpp:44:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
os << pair.second;
Any idea how to fix this? I ran into this problem earlier with templates, however there are no templates used here. Other answers on SO also involved templates and did not help me. An explanation of why this is happening would be appreciated too!
The command I used to compile: (MinGW, gcc 4.8.1)
g++ test.cpp -o test -std=c++11 -Wall
The full error message:
test.cpp: In function 'std::ostream& operator<<(std::ostream&, std::map<std::basic_string<char>, Point>&)':
test.cpp:44:14: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
os << pair.second;
^
In file included from c:\mingw\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\iostream:39:0,
from test.cpp:1:
c:\mingw\lib\gcc\x86_64-w64-mingw32\4.8.1\include\c++\ostream:602:5: error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Point]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
Thank you!!
Here
for(const auto& pair : m){
os << pair.first << DELIM;
os << pair.second;
}
pair is const, so pair.second will be const Point too, which can't match the parameter type Point& of operator<<.
Change the parameter type of Point for operator<< to const reference:
std::ostream& operator<<(std::ostream& os, const Point& p){
~~~~~
os << p.x << DELIM << p.y << DELIM;
return os;
}
Mostly, the argument passed to operator<< is not expected to be changed, so it's good practice to declare the type to const& for both operator<<.
std::ostream& operator<<(std::ostream& os, const Point& p){
std::ostream& operator<<(std::ostream& os, const std::map<std::string, Point>& m){
The argument passed to the overloaded << operator should be a constant reference, not a mutable reference.

defining numeric_limits max function for template class

I have problem with defining function max for template class. In this class we kept a numbers not as simple integers, but as vector of numbers in some numeral system. And with defining numeric_limits i need to return representation of maximal number founded on a defined number system.
And i get many errors, when i'm trying to return class with maximal representation, but it works when returns integer.
My template class:
template<int n,typename b_type=unsigned int,typename l_type=unsigned long long,long_type base=bases(DEC)>
class NSizeN
{
public:
int a_size = 0;
vector <b_type> place_number_vector; // number stored in the vector
NSizeN(int a){ //constructor
do {
place_number_vector.push_back(a % base);
a /= base;
a_size ++;
} while(a != 0);
}
void output(ostream& out, NSizeN& y)
{
for(int i=a_size - 1;i >= 0;i--)
{
cout << (l_type)place_number_vector[i] << ":";
}
}
friend ostream &operator<<(ostream& out, NSizeN& y)
{
y.output(out, y);
return out << endl;
}
}
At the end of .h file i have this :
namespace std{
template<int n,typename b_type,typename l_type,long_type base>
class numeric_limits < NSizeN< n, b_type, l_type, base> >{
public :
static NSizeN< n, b_type, l_type, base> max(){
NSizeN< n, b_type, l_type, base> c(base -1);
return c;
}
}
I've tried this with const, with constexpr, and it doesn't work. I've no idea how to get rid of this errors :
error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to'std::basic_ostream<char>&&'
std::cout << std::numeric_limits<NSizeN<3> >::max() << endl;
error: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = NSizeN<3>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
And this is what i'm trying do in main:
std::cout << std::numeric_limits<NSizeN<3> >::max() << endl;
This is my assignment so don't judge the way of doing this, because it's my teacher choice and I hope I presented my problem fairly comprehensive.
The problem that you are facing is that you try to bind a temporary returned by your max() function to a non-const reference for the output operator.
The cleanest solution would be to declare the output operator as:
friend ostream &operator<<(ostream& out, const NSizeN& y)
and your output function as
void output(ostream& out) const
Note, that I also removed the unused second parameter for the output function. The const reference can be bound to both l-values and r-values, so it will work for the temporary returned by the max() function as well.
Edit
As #n.m. pointed out, you also don't use the stream that is actually passed to the operator << and just use the std::cout. The proper way to implement it is to simply use the stream (in your case just replace the cout << ... with out << ... in your output function. This will let statements such as std::cerr << std::numeric_limits<NSizeN<3> >::max(); work as intended.

Printing a non type template inner class

I have a non type class template (e.g. Counted) that points to an instance of a class template (e.g. Counter). Everything works fine as long as both template classes are siblings, for example writing a print operator.
Now for several reasons, I want to move Counted inside of Counter as an inner class, and I find myself unable to write a printing operator.
Here's a working "sibling class" version, with the main code here:
template < class Count >
struct Counter {
using count_type = Count;
count_type instances = 0;
};
template < class Cnt, Cnt& c>
struct Counted {
using id_type = typename Cnt::count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
};
template < class Cnt, Cnt& c >
std::ostream& operator<<(std::ostream& os, Counted<Cnt,c> sib) {
os << "printing sibling " << sib.id;
return os;
}
using SCounter = Counter<std::size_t>;
SCounter sc;
using SCounted = Counted<SCounter, sc>;
Here's the not compiling "inner class" version with the main code here :
template < class Count >
struct Counter {
using count_type = Count;
count_type instances = 0;
template <Counter& c>
struct Counted {
using id_type = count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
};
};
template < class Count, Counter<Count>& c >
std::ostream& operator<<(std::ostream& os,
typename Counter<Count>::template Counted<c>& sib) {
os << "printing inner " << sib.id;
return os;
}
using SCounter = Counter<std::size_t>;
SCounter sc;
using SCounted = SCounter::Counted<sc>;
Errors:
prog.cpp: In function 'int main()':
prog.cpp:32:15: error: cannot bind 'std::ostream {aka std::basic_ostream<char>}' lvalue to 'std::basic_ostream<char>&&'
std::cout << j << std::endl;
^
In file included from /usr/include/c++/4.9/iostream:39:0,
from prog.cpp:1:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Counter<unsigned int>::Counted<(* & sc)>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
Is there a problem in my code, in my compiler, or is this simply not allowed by the standard ?
Koenig operators are what you want:
template <Counter& c>
struct Counted {
using id_type = count_type;
id_type id;
Counted() : id(c.instances) { ++c.instances; }
~Counted() { --c.instances; }
friend std::ostream& operator<<(
std::ostream& os,
Counted const& sib
) {
os << "printing inner " << sib.id;
return os;
}
};
};
here we create a friend operator<<. It will be found via ADL (or Koenig lookup) when you try to use << with a Counted instance.
A different function is created, and no template deduction is done, for each type of Counted.

Error when inserting string << overload C++

I am trying to overload the << operator on a class in C++. Whenever I insert a normal string, like the " " into the output stream I get compilation errors that I cannot make sense of. I have done this once before with no problems, so I am very confused.
friend std::ostream& operator<<(std::ostream& out, Variable v);
std::ostream& operator<<(std::ostream& out, Variable v) {
out << v.type;
out << " ";
out << v.name;
return out;
}
And here is the output:
src/Variable.cpp: In function 'std::ostream& operator<<(std::ostream&, Variable)':
src/Variable.cpp:35:9: error: no match for 'operator<<' in 'out << " "'
src/Variable.cpp:35:9: note: candidates are:
src/Variable.cpp:33:15: note: std::ostream& operator<<(std::ostream&, Variable)
src/Variable.cpp:33:15: note: no known conversion for argument 2 from 'const char [2]' to 'Variable'
In file included from /usr/local/Cellar/gcc/4.7.0/gcc/lib/gcc/x86_64-apple-darwin10.8.0/4.7.0/../../../../include/c++/4.7.0/string:54:0,
from src/../inc/Variable.h:4,
from src/Variable.cpp:1:
/usr/local/Cellar/gcc/4.7.0/gcc/lib/gcc/x86_64-apple-darwin10.8.0/4.7.0/../../../../include/c++/4.7.0/bits/basic_string.h:2750:5: note: template<class _CharT, class _Traits, class _Alloc> std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&, const std::basic_string<_CharT, _Traits, _Alloc>&)
/usr/local/Cellar/gcc/4.7.0/gcc/lib/gcc/x86_64-apple-darwin10.8.0/4.7.0/../../../../include/c++/4.7.0/bits/basic_string.h:2750:5: note: template argument deduction/substitution failed:
src/Variable.cpp:35:9: note: mismatched types 'const std::basic_string<_CharT, _Traits, _Alloc>' and 'const char [2]'
make: *** [bin/Variable.o] Error 1
Derp. I did not include iostream. However, this does not make much sense to me... since it worked whenever I did not add a string to the ostream. I would think that the compiler would not be able to find ostream at all, and would complain about that
#include <utility>
#include <iostream>
template <typename T1, typename T2>
std::ostream& operator<< (std::ostream& out, const std::pair<T1, T2>& v)
{
out << v.first;
out << " ";
out << v.second << std::endl;
return out;
}
int main()
{
std::pair<int, int> a = std::make_pair(12, 124);
std::cout << a << std::endl;
return EXIT_SUCCESS;
}
Its an example how to declare and implement an operator <<
I will show your solution in code
#include <iostream>
#include <string>
/* our custom class */
class Developer
{
public:
Developer(const std::string& name, int age) :
m_name(name),
m_age(age)
{}
const std::string& name() const { return m_name; }
int age() const { return m_age; }
private:
std::string m_name;
int m_age;
};
/* overloaded operator<< for output of custom class Developer */
std::ostream& operator<< (std::ostream& stream, const Developer& developer)
{
stream << "Developer name:\t" << developer.name() << std::endl;
stream << "Developer age:\t" << developer.age() << std::endl;
return stream;
}
/* test custom operator<< for class Developer */
int main(int argc, const char** argv)
{
Developer max("Maxim", 23);
std::cout << max;
return 0;
}