I am trying to overload the output operator to print from a class with a template that uses non-type values. However, I keep getting the error
"unexpected token 'identifier', expected ';'"
in the operator's function body. How do I fix either my friend declaration or my operator overload definition to avoid this error?
template <int N, int M> class Screen {
friend std::ostream& operator<< (std::ostream&, const Screen&);
public:
Screen(): width(N), height(M) {}
int width = 0;
int height = 0;
};
template <int N, int M>
std::ostream& operator<< (std::ostream& os, const Screen<N, M>& a)
{
os << a.width << ":" a.height;
return os;
}
You have forgotten a <<
// ..................VV
os << a.width << ":" << a.height;
Related
Trying to code a better version of array type i have run into an issue. For some reason the declaration doesnt work. It throws at me bunch of weird errors. Tried looking up the issue but havent found anything so far. Here is the code:
Template <class T>
class SafeArray {
private:
int size;
int elements;
int index;
T* arr;
public:
SafeArray(int n);
~SafeArray();
void push_back(T item);
void resize(int size);
friend std::ostream& operator << (std::ostream& os, const SafeArray<T>& ar)
};
And the implementation outside the class:
template<class T>
std::ostream& operator << <T> (std::ostream& os, const SafeArray<T> & arr) {
for (int i = 0; i < arr.elements; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return os;
}
If you want friend template, the friend declaration should be
template <class T>
class SafeArray {
...
template<class X>
friend std::ostream& operator << (std::ostream& os, const SafeArray<X>& ar);
};
the implementation should be
template<class T>
std::ostream& operator << (std::ostream& os, const SafeArray<T> & arr) {
...
}
LIVE
BTW: In the implementation of operator<<, I think std::cout << arr[i] << " "; should be std::cout << arr.arr[i] << " ";.
I'm sorry if this question has been answered allready but I have a read a lot of questions considering overloading this operator in a template class but I haven't found a particular case like mine.
This is my code:
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;
template <typename T>
class Class
{
T x;
public:
friend ostream& operator << (const Class<T>&, ostream& out);
};
template <typename T>
ostream& operator << (const Class<T>&, ostream& out)
{
return (out << out.x << endl);
}
int main()
{
Class<short> object;
cout << object << endl;
}
And I get this error on last line:
Error 1 error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'Class' (or there is no acceptable conversion) g:\ucenje\objektno orijentirano programiranje\template3\template3\main.cpp 25 1 template3
1.std::ostream should be the 1st parameter of operator<<, so
template <typename T>
ostream& operator << (const Class<T>&, ostream& out)
should be
template <typename T>
ostream& operator << (ostream& out, const Class<T>& c)
2.You defined operator<< as a template function, but friend ostream& operator << (const Class<T>&, ostream& out); points to a non-template function, you should change it to
friend ostream& operator<< <T>(ostream& out, const Class<T>& c);
And add some forward declarations before the declaration of the class:
template <typename T>
class Class;
template <typename T>
ostream& operator << (ostream& out, const Class<T>& c);
LIVE1
Or you can define operator<< as non-template function inside the definition of class.
template <typename T>
class Class
{
T x;
public:
friend ostream& operator<< (ostream& out, const Class<T>& c)
{
out << c.x << endl;
return out;
}
};
LIVE2
The arguments to the operator<< functions have been switched, it should be e.g
friend ostream& operator << (ostream& out, const Class<T>&1);
The left-hand side of all binary operators is always the first argument, and the right-hand side is the second argument.
I'm trying to make << output an entire matrix which I wrote a template for. Not sure why this isn't working, the error is:
error: no match for 'operator[]' (operand types are 'matrix<int' and 'int')
candidate is:
matrix<Comparable> matrix<Comparable>::operator[](matrix<Comparable>&) [with Comparable = int]|
no known conversion for argument 1 from 'int' to 'matrix<int>&'|
which refers to this line: o << rhs[ i ][ j ]. Am I supposed to overload [ ] as well?
matrix.h:
template <typename Comparable>
class matrix
{
private:
size_t num_cols_;
size_t num_rows_;
Comparable **array_;
public:
friend ostream& operator<< (ostream& o, const matrix<Comparable> & rhs);
size_t NumRows();
size_t NumCols();
};
matrix.cpp:
template <typename Comparable>
ostream& operator<< (ostream& o, matrix<Comparable> & rhs){
size_t c = rhs.NumRows();
size_t d = rhs.NumCols();
for (int i = 0; i < c; i++){
for (int j = 0; j < d; j++){
o << rhs[i][j]; //error
}
}
}
template <typename Comparable>
size_t matrix<Comparable>::NumRows(){
return num_rows_;
}
template <typename Comparable>
size_t matrix<Comparable>::NumCols(){
return num_cols_;
}
And probably irrelevant but I implemented the matrix like this:
array_ = new Comparable*[num_rows_];
for (int i = 0; i < num_rows_; i++){
array_[i] = new Comparable[num_cols_];
Your function signatures don't match:
ostream& operator<< (ostream& o, const matrix<Comparable> & rhs);
is not
template <typename Comparable>
ostream& operator<< (ostream& o, matrix<Comparable> & rhs);
Notice that one is not a template, and the other is. Also, the first has a const reference argument for rhs and the second has just a reference. This mismatch means the function you define isn't Matrix's friend, and so can't access the private (or protected members of Matrix)
What you want is to declare a templated function, and then inform the compiler that a single instantiation (say ostream& operator<<(ostream& out, const matrix<int>& val) ) is the single function you want to be friends with matrix<int>.
To do this, you need to declare that you want only a specific version of the function template, and to do that you need to declare the template, and to do that you need to declare the templated class.
Ultimately that whole chain of declarations might look something like this:
#include <iostream>
// forward declare the class so the compiler knows what's up at the
// templated operator<< declaration.
template <typename T>
class Foo;
// forward declare the templated operator<< so the compiler knows you're
// 'friend'ing a specific instantiation of this template in the
// class definition.
template <typename T>
std::ostream& operator<<(std::ostream& out, const Foo<T>& value);
template <typename T>
class Foo{
// declare the instantiation of the operator<< template that shares
// T with the class template to be a friend:
// operator<<<> can be separated out into operator<< <>
friend std::ostream& operator<<<>(std::ostream& out, const Foo<T>& value);
int bar_;
public:
Foo(int bar) : bar_{bar}{}
};
// now that you know the contents of `Foo<T>`, define the templated operator<<
template <typename T>
std::ostream& operator<<(std::ostream& out, const Foo<T>& value){
return std::cout << "Foo: " << value.bar_;
}
int main(){
Foo<int>
a{2},
b{3};
std::cout << a << '\n' << b;
}
Live on Coliru
You can read further on Template Friends on the C++ Super-FAQ.
You can declare a get function to access array_ instead of making it as an public member;
I'm getting "Unresolved external symbols" for the following code:
template <int n> class Fibo
{
private:
int pre, cur, next, tmp;
public:
Fibo() : pre(1), cur(1), next(2), tmp(0) {}
int get()
{
if(n == 0 || n == 1) return 1;
for(int i = 2; i < n; ++i)
{
next = pre + cur;
tmp = cur;
cur = next;
pre = tmp;
} return pre + cur;
}
friend ostream& operator<< (ostream& out, Fibo<n>& f);
};
template<int n>
ostream& operator<< (ostream& out, Fibo<n>& f)
{
out << f.get();
return out;
}
int main()
{
Fibo<5> a;
cout << a << endl;
cin.get();
}
I get this compilation error when I'm trying to print a:
cout << a << endl;. When I'm printing "normaly", i.e. cout << a.get() << endl, no errors popped.
I know that Unresolved external symbols error are associated with declared function that didn't implemented. is that the case in my code? I can't find it.
There are a couple ways to handle this:
template <int n> class Fibo ; // Forward declaration
// Definition, you could also forward declare here and define after the class
template<int n>
ostream& operator<< (ostream& out, Fibo<n>& f)
{
out << f.get();
return out;
}
template <int n> class Fibo
{
// Don't forget <> to tell its a template
friend ostream& operator<< <> (ostream& out, Fibo<n>& f);
};
The above way is verbose, but you could also define the friend in-class:
template <int n> class Fibo
{
// Note this is not a template
friend ostream& operator<< (ostream& out, Fibo& f)
{
out << f.get();
return out;
}
};
The in-class definition will define a friend function for each instantiation, i.e. Fibo<1>, Fibo<2>, etc.
GCC compiler messages:
test.C:22:57: warning: friend declaration ‘std::ostream& operator<<(std::ostream&,
Fibo<n>&)’ declares a non-template function [-Wnon-template-friend]
test.C:22:57: note: (if this is not what you intended, make sure the function
template has already been declared and add <> after the function name here)
Pretty self-explanatory I think.
class W
{
private:
long m_val1, m_val2;
public:
W(long& val1, long& val2):m_val1(val1), m_val2(val2) {}
template<class T>
friend std::ostream& operator<<(std::ostream& os, const T& w);
};
class X
{
private:
long m_val1, m_val2;
public:
X(const long& val1, long& val2):m_val1(val1), m_val2(val2) {}
template<class T>
friend std::ostream& operator<<(std::ostream& os, const T& x);
};
template<class T>
std::ostream& operator<<(std::ostream& os, const T& obj)
{
os << "m_val1: " << obj.m_val1 << ", m_val2: " << obj.m_val2 << endl;
}
It does NOT work. Can anyone point out what do I miss? Thanks.
In addition, this results in "error C2593: 'operation <<' is ambiguous" wherever "cout << "some string";" is used.
You have created an output operator that can be called for all types, when it's obvious it should only be able to be used for the W and X classes. You need to narrow the scope of the output operator function.
The compiler can deduce the template from the call. So when you call os << "m_val1: ", based on your template implementation, it creates
template<class T>
std::ostream& operator<<(std::ostream& os, const string& obj)
witch already exists. More info about template argument deduction in http://accu.org/index.php/journals/409