Receiving Error C2670 in Visual Studios 2019 - c++

I've searched throughout my entire code, and there aren't any other issues except for this section. The semicolon at the end of the forward-slashed line is the issue. Is there something I'm missing? Full error message below.
source\repos\Square Matrix\SquareMatrix.cpp(108,27): error C2760: syntax error: unexpected token ';', expected '{'
#pragma once
#include <stdexcept>
#include "SquareMatrix.h"
template<typename T>
class SquareMatrix
{
private:
size_t _size; //will be the size of the array. size_t makes sure i only use nonnegative integers for the size
T **_ptr;
public:
SquareMatrix(); //zero parameter constructor
SquareMatrix(const SquareMatrix& rhs); //copy constructor
~SquareMatrix(); //destructor
SquareMatrix(SquareMatrix&& rhs); //Move Constructor
SquareMatrix& operator=(const SquareMatrix& rhs); //Copy assignment Operator
SquareMatrix& operator=(SquareMatrix&& rhs); //Move Assignment Operator
void resize(size_t new_size);
T& at(int row, int column);
size_t size() const;
};
template<typename T>
void SquareMatrix<T>::resize(size_t new_size)
{
std::cout << "Input size of the new matrix: " << std::endl;
std::cin >> new_size;
for (int i = 0; i < _size; i++)
{
delete[] _ptr[i];
}
if (_ptr != nullptr)
delete[] _ptr;
if (new_size != _size)
{
_ptr = new T * [new_size];
for (int i = 0; i < new_size; i++)
{
// _ptr[i] = T *[new_size]; //
}
}
}

It seems that the issue might be in the declaration of your class SquareMatrix. You have not posted it so I cant tell for sure but I tested your method implementation with a dummy class and I don't get any errors in compilation.
Make sure that your class declaration and method declaration have this syntax:
template<class T>
class SquareMatrix {
T a, b;
public:
void resize(size_t new_size);
};
You can review the section on Class Templates to get some examples and a more through explanation.
http://www.cplusplus.com/doc/oldtutorial/templates/

Related

Use of class template requires template arguments

Hi I'm still wondering why I'm getting this error message :
Use of class template 'Array' requires template arguments
Header :
#ifndef Array_h
#define Array_h
template< typename T>
class Array
{
public:
Array(int = 5);
Array( const Array &);
const Array &operator=(Array &);
T &operator[](int);
T operator[](int) const;
// getters and setters
int getSize() const;
void setSize(int);
~Array();
private:
int size;
T *ptr;
bool checkRange(int);
};
#endif
CPP file
template< typename T >
const Array &Array< T >::operator=(Array &other)
{
if( &other != this)
{
if( other.getSize != this->size)
{
delete [] ptr;
size = other.getSize;
ptr = new T[size];
}
for ( int i = 0; i < size; i++)
{
ptr[i] = other[i];
}
}
return *this;
}
Problem seems to do with returning a const reference to object.
Thanks.
Before the compiler sees Array<T>::, it doesn't know that you are defining a member of the class template, and therefore you cannot use the injected-class-name Array as shorthand for Array<T>. You'll need to write const Array<T> &.
And you got constness backwards in your assignment operator. It should take a const reference and return a non-const one.
Also, Why can templates only be implemented in the header file?

Can't access global Swap function within from a class

this is my first question on the site.
A little problem met me today. I can't call a global function Swap within a assignment operator and move constructor from the DynamicArray template class. When I try to do this I get an error C2660 saying:
'DynamicArray<int>::Swap' : function does not take 2 arguments.
It's strange for me, because I can call this function with 2 arguments in main function. Does anyone know what is the reason of that?
#include <iostream>
#include <stdexcept>
using std::cout;
using std::cin;
using std::endl;
template <typename T>
class DynamicArray;
template <typename T>
inline void Swap(DynamicArray<T>& lhs, DynamicArray<T>& rhs) {
lhs.Swap(rhs);
}
template <typename T>
class DynamicArray {
public:
DynamicArray(size_t Size = 0, T Content = T())
: m_Size(Size), m_Array(Size ? new T[m_Size] : nullptr) {
for (size_t i = 0; i < m_Size; ++i) {
m_Array[i] = Content;
}
}
DynamicArray(const DynamicArray<T>& rhs)
: m_Size(rhs.m_Size), m_Array(m_Size ? new T[m_Size] : nullptr) {
std::copy(rhs.m_Array, rhs.m_Array + m_Size, m_Array);
}
DynamicArray(DynamicArray<T>&& rhs)
: DynamicArray<T>() {
this->Swap(rhs);
//Swap(*this, rhs); //C2660
}
DynamicArray<T>& operator= (DynamicArray<T> rhs) {
this->Swap(rhs);
//Swap(*this, rhs); //C2660
return *this;
}
~DynamicArray() {
delete [] m_Array;
}
void Swap(DynamicArray<T>& rhs) {
std::swap(m_Size, rhs.m_Size);
std::swap(m_Array, rhs.m_Array);
}
private:
size_t m_Size;
T* m_Array;
};
int main() {
DynamicArray<int> DA1(4, 64);
DynamicArray<int> DA2(2, 33);
DA1 = std::move(DA2); //using move constructor
DynamicArray<int> DA3(8, 4);
DynamicArray<int> DA4(2, 55);
DA3 = DA4; //using assignment operator
Swap(DA1, DA3); //here I can call this function with 2 arguments
cout << endl;
system("pause");
}
To specify that you want to call the global Swap, you should prefix it perhaps with the scope resolution operator ::, like this ::Swap(...).
It's been a long while since I last coded in c++ but I believe the member Swap method takes precedence in the resolution of the Swap symbol, when it's used within a member method.
To explicitly use std::swap function try:
void Swap(DynamicArray<T>& rhs)
{
using std::swap;
std::swap(m_Size, rhs.m_Size);
std::swap(m_Array, rhs.m_Array);
}
DynamicArray(DynamicArray<T>&& rhs)
: DynamicArray<T>()
{
this->Swap(rhs);
}
...
Swap<int>( DA1, DA3 );
but I would remove global inline void Swap(DynamicArray<T> and start using:
DA1.Swap( DA3 );

How to make a template class a data member of another class?

So what I'm trying to do is write a class with a template class as its data member. This is part of my homework.
So far this is what I have:
letter_frequencies.h
#include "ltr_freq_pair.h"
#include "darray.h"
class letter_frequencies
{
private:
darray<letterFrequencyStruct> array;
public:
letter_frequencies();
void outputFrequencies();
};
letter_frequencies.cpp
#include <iostream>
#include "letter_frequencies.h"
letter_frequencies::letter_frequencies()
{}
void letter_frequencies::outputFrequencies()
{
for(int index = 0; index < 26; index ++)
{
std::cout << "\n" << array[index].letter;
std::cout << " " << array[index].frequency;
}
}
Everything compiles, but once I run the program it has this error:
a.out: darray.cpp:44: T& darray<T>::operator[](unsigned int) [with T = letterFrequencyStruct]: Assertion 'index < used' failed.
Abort (core dumped)
The code snippet I'm trying to use for this class is:
//Check if Class Works
letter_frequencies array;
array.outputFrequencies();
Right now, the darray works just fine and the program does exactly what I need it to do, but one of the requirements is to have a class named letter_frequency with a data member darray<structTypename> name, which is why I'm fussing with this in the first place.
Also, how would I make the class call the explicit constructor for the darray? I want to set the size to 26.
darray.h
#ifndef DARRAY_H
#define DARRAY_H
#include <iostream>
template <typename T>
class darray
{
public:
//Constructors
darray();
darray(const darray&);
explicit darray(unsigned);
//Destructor
~darray();
//Constant Members
unsigned size() const {return used;}
unsigned capacity() const {return cap;}
//Modification Members
T& operator [] (unsigned);
void pop_back();
void push_back(const T&);
const T* find(const T&) const;
void resize(unsigned);
//Operators
T& operator = (const darray&);
bool operator == (const darray&) const;
//Friends
template <typename X>
friend std::ostream& operator << (std::ostream& output, const darray<X>& array);
private:
T* arr;
unsigned used, cap;
};
template <typename X>
std::ostream& operator << (std::ostream& output, const darray<X>& array)
{
for(int index = 0; index < array.size; index++)
{
output << index << array[index];
}
return output;
}
#include "darray.cpp"
#endif
As I mentioned before, you'd have to make letter_frequencies constructor like this:
letter_frequencies::letter_frequencies() : array(26) {
}
(so you initialize the array with the necessary number of elements).
BUT: I don't think you should make your own home-grown array when std::vector would be better...

Why isn't my compiler recognizing my class "index" as a type within the class implementation

So I've declared my class, "index", in the file index.h thusly:
#ifndef INDEX_H
#define INDEX_H
#include <iostream>
#include <sstream>
#include "word.h"
#include "heap.h"
using namespace std;
class index
{
public:
index();
~index();
index(const index &other);
index& operator = (const index &other);
void push(word<string> w);
word<string> pop();
private:
heap<word<string> > orchard[26];
void nukem();
void copy(const index &other);
};
#endif
And the subsequent definition:
#include "index.h"
index::index()
{}
index::~index()
{
nukem();
}
index::index(const index &other)
{
copy(other);
}
index& index::operator = (const index &other)
{
if(this != &other)
copy(other);
return *this;
}
void index::push(word<string> w)
{
orchard[w.data[0]]<<w;
}
word<string> index::pop()
{
word<string> popped;
int i = 0;
for(; orchard[i].empty(); i++);
orchard[i]>>popped;
return popped;
}
void index::nukem()
{
for(int i = 0; i < 26; i++)
orchard[i].clear();
}
void index::copy(const index &other)
{
for(int i = 0; i < 26; i++)
orchard[i] = other.orchard[i];
}
In the definition of the assignment operator, I get this compiler error from xcode:
Expected constructor, destructor or type conversion before '&' token
Which made me think it was a type problem, so I deleted the '&' and tried to recompile, which gave me this error on the same line:
'index' is not a type
Both errors appear on the first line of the following code:
index& index::operator = (const index &other)
{
if(this != &other)
copy(other);
return *this;
}
Why is the compiler not recognizing that index is a type declared in the header file? I've looked back at previous classes I've written and can't see where I'm going wrong. I think it's probably a bonehead mistake, but I'm not seeing it. All help is appreciated.

templated code not working while non-templated code works!

I spent several hours, completely stuck when I realized that only the templated version of my code has a bug.
In the following code, when pushing_back elements in the myMap, the original vectors myVec1 and myVec2 are modified and contain garbage at the end of the execution. If I un-template everything, just replacing template<T> by double, then the code works fine as I would expect (the original arrays are untouched).
The funny thing is if I put a cout in the copy constructor, it does not get called if the code is templated. But it gets called if I replace the copy constructor with Vector<T2> by the original type Vector<T>, and then everything work fine.
Why wouldn't the compiler know that T2==T since I only use double?
(note, the code has been made as short as possible so as to show the errors - I thus removed accessors, made everything public etc.).
#include <vector>
#include <map>
template<class T>
class Vector{
public:
Vector():n(0),data(0){};
Vector(int N):n(N),data(new T[N]){};
Vector(T x, T y):n(2),data(new T[2]){data[0]=x; data[1]=y;};
template<class T2> Vector(const Vector<T2>& rhs):n(rhs.n), data(new T[n])
{
for (int i=0; i<n; i++)
data[i] = T(rhs.data[i]);
}
~Vector(){delete[] data;}
Vector& operator=(const Vector& rhs)
{
if (rhs.n != n)
{
if (data)
delete[] data;
data = new T[rhs.n];
}
n = rhs.n;
memcpy(data, rhs.data, n*sizeof(T));
return *this;
}
T& operator[](int i){return data[i];}
const T& operator[](int i) const {return data[i];}
int n;
T* data;
};
typedef Vector<double> Vectord;
template <class T> inline bool operator<(const Vector<T>& v1, const Vector<T>& v2)
{
for (int i=0; i<v1.n; i++)
{
if (v1[i]<v2[i]) return true;
if (v1[i]>v2[i]) return false;
}
return false;
}
int main(int argc, char** argv)
{
std::vector<Vectord> myVec1(3);
myVec1[0] = Vectord(1.,3.);
myVec1[1] = Vectord(3.,3.);
myVec1[2] = Vectord(1.,5.);
std::vector<Vectord> myVec2(3);
myVec2[0] = Vectord(4.,1.);
myVec2[1] = Vectord(2.,5.);
myVec2[2] = Vectord(6.,5.);
std::map<Vectord, std::vector<Vectord> > myMap;
for (int i=0; i<3; i++)
{
myMap[myVec1[i]].push_back(myVec2[i]);
}
return 0;
}
A templated constructor is never a copy constructor.
So your class is using the automatically generated copy constructor.
Cheers & hth.,