Greetings and thank you in advance!
I'm working in macOS X 10.12; Eclipse Neon 4.6, Compiling using macOS X GCC. I am receiving the following error:
../matrix.h:82:1: error: 'Matx' is not a class, namespace, or enumeration
`Matx::~matx(){`
`^`
`../matrix.h:27:7: note: 'Matx' declared here`
The error is confusing due to the following matrix.h file:
#ifndef MATRIX_H_
#define MATRIX_H_
#include <iostream>
template <class T>
class Matx {
int ROWS, COLS ;
int colix[COLS], rowix[ROWS] ;
T ** array ;
Matx(int, int) ;
~Matx() ;
void rowSwap() ;
void size( void ) ;
void swapRows(int i1, int i2) { std::swap(this->array[i1], this->array[i2]); }
void printMat( void ) ;
};// end class matrix
template <class T>
Matx::~Matx(){
delete this->array ;
}// end ~matx()
Note there are a few more functions in the file, but the error is consistent across all of them. I have tried defining the functions with scope resolution and without, i.e. Matx::~m but to no avail. Any help is much appreciated!
You should write the definition of the function like this:
template <class T>
Matx<T>::~Matx(){
delete this->array ;
}// end ~matx()
This Part is wrong.
int ROWS, COLS ;
int colix[COLS], rowix[ROWS] ;
your're defining arrays of size COLS and ROWS. But these are non-const member variables. You need compile time expressions. For example:
static constexpr int ROWS = 4;
static constexpr int COLS = 4;
Related
I try to run a .cpp with a .hpp file in Linux using this command: g++ -c main.cpp but I have this error about calloc():
error: there are no arguments to ‘calloc’ that depend on a template parameter, so a declaration of ‘calloc’ must be available [-fpermissive]
Tr=(T *)calloc(Rows*Colomns, sizeof(T));
In member function ‘T* MyMatrix::Adjoint()’:
MyMatrix.hpp:276:35: error: there are no arguments to ‘calloc’ that depend on a template parameter, so a declaration of ‘calloc’ must be available [-fpermissive]
Temp = (T*)calloc(N*N, sizeof(T));
I noticed that this code works in Microsoft Visual Studio:
#pragma once
#include <iostream>
#include <fstream>
template <typename T>
class MyMatrix {
private:
int Rows;
int Colomns;
T* A; //Matricea
T* Tr; //Transpusa acesteia
float* Inv; //Inversa
public:
MyMatrix(int L, int C)
{
Rows = L;
Colomns = C;
A = (T*)calloc(Rows * Colomns, sizeof(T));
if (A == NULL)
throw("Eroare la alocarea matricii! :(");
}
MyMatrix(T* S, int L, int C)
: MyMatrix(L, C)
{
for (int i = 0; i < Rows * Colomns; ++i)
A[i] = S[i];
}
~MyMatrix() { free(A); }
void Transposed()
{
Tr = (T*)calloc(Rows * Colomns, sizeof(T));
for (int i = 0; i < Colomns; ++i)
for (int j = 0; j < Rows; ++j)
Tr[j * Colomns + i] = A[i * Rows + j];
}
void Inverse()
{ //some code
T* Adj = Adjoint();
Inv = (float*)calloc(Rows * Rows, sizeof(float));
for (int i = 0; i < this->Rows * this->Rows; ++i)
Inv[i] = Adj[i] / (float)Det;
}
};
#endif // MYMATRIX_HPP_INCLUDED
a declaration of ‘calloc’ must be available
The solution is to declare calloc before using it. Since it is a standard function, it must be declared by including the standard header that is specified to declare it.
calloc is declared in the header <stdlib.h>. Note that the .h suffixed headers from the C standard library are deprecated in favour of using the c prefixed headers such as <cstdlib>. However, the c prefixed headers declare the functions in the std namespace which you have failed to use in this case.
So the complete solution is to include <cstdlib>, and use std::calloc.
However, you don't need to use calloc at all. Better solution is to use std::make_unique or std::vector.
As the error message suggests, the g++ compiler used here does not have an implementation wherein the second parameter is a template type i.e. the compiler recognizes the arguments when the second argument is of type int or float because these are the types the compiler knows about its 'calloc' implementation works with these types BUT it does not recognize when the second argument is of a templated type.
Visual Studio used here probably has an implementation which allows template types to be passed to 'calloc'.
Maybe you can try updating the g++ compiler to the latest and then it might support what you are trying to do here.
hope this helps!
I have an Array class that is inheriting from BaseArray class. In BaseArray, I have the protected member variables data_ and cur_size_. The Array class introduces a resize function. The problem I am encountering is that none of the protected member variables from BaseArray are seeming to be accessed in the resize function.
EDIT: Solved the max_size_ problem, but the cur_size_ and data_ file persists
Inheritance? Scope? Help?
The Error:
In file included from Array.h:41:0,
from driver.cpp:6:
Array.cpp: In member function ‘void Array<T>::resize(size_t)’:
Array.cpp:29:5: error: ‘data_’ was not declared in this scope
data_=data_;
^
Array.cpp:30:18: error: ‘cur_size_’ was not declared in this scope
if (new_size>cur_size_)
^
Array.cpp:37:5: error: ‘cur_size_’ was not declared in this scope
cur_size_=new_size;
^
The Code:
BaseArray.h:
#ifndef _BASEARRAY_H_
#define _BASEARRAY_H_
#include <cstring>
template <typename T>
class BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
//constructors, destructor and methods…
protected:
/// Pointer to the actual data. m
char * data_;
/// Current size of the BaseArray.
size_t cur_size_;
};
#include "BaseArray.inl"
#include "BaseArray.cpp"
#endif // !defined _BASEARRAY_H_
Array.h:
#ifndef _ARRAY_H_
#define _ARRAY_H_
#include <cstring>
#include "BaseArray.h"
template <typename T>
class Array: public BaseArray<T> //inheriting from BaseArray
{
public:
/// Type definition of the element type.
typedef T type;
/// Default constructor.
Array (void);
Array (const Array & arr);
/// Destructor.
~Array (void);
const Array & operator = (const Array & rhs);
void resize (size_t new_size);
private:
size_t max_size_; //introduces max_size
};
#include "Array.inl"
#include "Array.cpp"
#endif // !defined _ARRAY_H_
Array.cpp:
#include "BaseArray.h"
#include "Array.h"
#include <stdexcept>
#include <iostream>
template <typename T>
Array <T>::Array (void): BaseArray<T>()
{
std::cout<<"Array def const called"<<std::endl;
}
template <typename T>
Array <T>::Array (const Array & array): BaseArray<T>(array)
{
}
template <typename T>
Array <T>::~Array (void)
{
}
template <typename T>
void Array <T>::resize (size_t new_size)
{
this->data_= this->data_;
if (new_size>this->cur_size_)
{
max_size_ = new_size-this->cur_size_-1;
this->cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
this->data_[max_size_]=0;
}
this->cur_size_=new_size;
}
/* Also tried it like this:
template <typename T>
void Array <T>::resize (size_t new_size)
{
BaseArray<T>::data_= BaseArray<T>::data_;
if (new_size>BaseArray<T>::cur_size_)
{
max_size_ = new_size-BaseArray<T>::cur_size_-1;
BaseArray<T>::cur_size_=new_size;
for (max_size_; max_size_<=new_size; max_size_++)
BaseArray<T>::data_[max_size_]=0;
}
BaseArray<T>::cur_size_=new_size;
} */
regarding the first error, you have no max_size() member declared in Array.
regarding the second error, name lookup in templates follows a two stage logic, where non dependent expressions are looked up at definition point, whereas dependent expressions are looked up at instantiation point;
This means that when the compiler sees data_ it thinks it's a variable located somewhere else; at best, it won't find it giving you an error, at worst, it will give you the wrong variable !
In order to solve the problem, you need to make that a dependent expression, the most obvious way being replacing all data_ with this->data_, etc...
regarding your code organization, define your templates into a single header file; if you really want to split member implementations place them in a single file with a sensible file extension ( inl is ok, cpp is not )...
I'm having this problem, where I get weird syntax errors in my skip list implementation and seriously have no clue what could cause this.
This is the code:
skipnode.h:
template <typename T>
class SkipNode
{
public:
T data;
SkipNode<T> **next;
SkipNode(T d, int level);
~SkipNode();
};
skipnode.cpp
#include "skipnode.h"
template<typename T>
SkipNode<T>::SkipNode(T d, int level)
{
data = d;
next = new SkipNode<T>*[level];
for (int i = 0; i <= level; i++)
next[i] = 0;
}
template<typename T>
SkipNode<T>::~SkipNode()
{
delete [] next;
}
Skiplist.h
#include "skipnode.cpp"
#define MAXLEVEL 4;
template<typename T>
class SkipList
{
public:
SkipList();
~SkipList();
int randLvl(int max);
T search(T);
void insert(T);
private:
SkipNode<T> *root;
};
Skiplist.cpp
#include "skiplist.h"
template<typename T>
SkipList<T>::SkipList()
{
root = new SkipNode<T>(0,MAXLEVEL);
}
When I declare root in Skiplist() I get the following error:
error C2143: syntax error : missing ')' before ';'
Can anyone help me out? Thanks in advance.
Edit: Fixed code, so show includes
The root cause of your problem is here:
#define MAXLEVEL 4;
The semicolon is present in the macro expansion, so after the preprocessor pass you end up with:
root = new SkipNode<T>(0, 4;);
Which is a syntax error (extra semicolon before the closing parenthesis).
To fix it, omit the semicolon in your macro definition:
#define MAXLEVEL 4
You need to include skipnode.h, or at least declare
template <typename T> class SkipNode;
before you can use the name SkipNode in the definition of SkipList.
You'll also (almost certainly) need to define the template member functions in your headers, not source files, as explained here.
You also have a problem with
#define MAXLEVEL 4;
which will expand to 4;, inserting a rogue ; in the middle of an expression. Use a less broken macro
#define MAXLEVEL 4
or, better still, a language-level constant
const int max_level = 4;
I have a .cu file that when compiled on its own, right click and select compile, it compiles just fine, but when I have another header file, a c++ header file, that calls this .cu file the build fails. The .cu file properties have been edited to build with the CUDA compiler. The errors that I am getting are 'blockIdx': undeclared identifier 'blockDim': undeclared identifier, etc.. basically errors that I would expect compiling cuda code with a c++ compiler. So is it possible to include a .cu cuda code in a c++ header?
Here is the .cu file:
Matrix.cu
#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_device_runtime_api.h>
#define BLOCKSIZE 32
using namespace std;
template<typename T> class Matrix
{
public:
typedef T value_type;
~Matrix();
Matrix();
Matrix(int rows, int columns);
int height;
int width;
int stride;
size_t size;
void CreateIdentity(Matrix<T>&I);
private:
vector<T> elements;
T* firstElement;
};
template<typename T>
Matrix<T>::~Matrix()
{
}
template<typename T>
Matrix<T>::Matrix()
{
}
template<typename T>
Matrix<T>::Matrix(int rows, int columns)
{
height = rows;
width = columns;
stride = columns; //in row major order this is equal to the # of columns
elements.resize(rows*columns);
firstElement = elements.data();
size = height*width*sizeof(T);
}
__global__ void IdentityMatrixKernel(float* identity, int size)
{
int index_x = blockIdx.x * blockDim.x + threadIdx.x;
int index_y = blockIdx.y * blockDim.y + threadIdx.y;
// map the two 2D indices to a single linear, 1D index
int grid_width = gridDim.x * blockDim.x;
int index = index_y * grid_width + index_x;
// map the two 2D block indices to a single linear, 1D block index
//int result = blockIdx.y * gridDim.x + blockIdx.x;
// write out the result
if (index % (size+1))
{
identity[index] = 0;
}
else
{
identity[index] = 1;
}
}
template<typename T>
void Matrix<T>::CreateIdentity(Matrix<T>&I)
{
float* d_I;
int size1 = I.height;
int size2 = I.height*I.width*sizeof(float);
cudaMalloc(&d_I,size2);
dim3 block_size;
block_size.x = BLOCKSIZE;
block_size.y = BLOCKSIZE;
dim3 grid_size;
grid_size.x = size1/ block_size.x + 1;
grid_size.y = size1/ block_size.y + 1;
IdentityMatrixKernel<<<block_size,grid_size>>>(d_I,size1);
cudaMemcpy(I.GetPointer(),d_I,size2,cudaMemcpyDeviceToHost);
cudaFree(d_I);
}
And here is the header file that #include "Matrix.cu"
Element.h
#pragma once
#include "Matrix.cu"
#include <vector>
using namespace std;
class Element
{
public:
Element(void);
~Element(void);
Element(int iD, float k, vector<int> nodes);
Element(int iD, vector<int> nodes, int pId);
void SetElementType(DOF type);
DOF GetElementType();
int GetNodeId(int index);
int GetNodesPerElement();
int GetPartId();
void CalculateShapeFunctions(Matrix<int> spaceCoordinates);
void CalculateSShapeDerivative(Matrix<int> spaceCoordinates);
void CalculateTShapeDerivative(Matrix<int> spaceCoordinates);
Matrix<float> GetShapeFunctions();
float GetSShapeDerivative(int row, int column);
float GetTShapeDerivative(int row, int column);
void SetStrainDisplacement(Matrix<float> B);
Matrix<float> GetStrainDisplacement();
private:
int elementId;
float stiffness;
vector<int> nodeIds;
DOF elementType;
int partId;
Matrix<float> shapeFunctions;
Matrix<float> sShapeDerivative;
Matrix<float> tShapeDerivative;
Matrix<float> strainDisplacement;
};
EDIT:
So I have been directed to try and separate the template class member functions implementing cuda into a .cu file while keeping the template class definition and any template member functions not using cuda in the original header file. This does seem on the right path, c++ compiler compiles the .h file while the cuda compiler does the .cu, but I am having trouble getting rid of link errors. I understand that I need to explicitly instantiate my template class for the types I need in the .cu file to avoid link errors, but I seem to still get them.
I instantiated my template class at the end of the .cu file as follows:
template class Matrix<float>;
template class Matrix<int>;
template class Matrix<string>;
I am now getting link errors to the template member functions using cuda.
Answer: .cu files cannot be used as #include "file.cu" like header files because they will be compiled with the C++ compiler not cuda. The solution was to move anything implementing cuda into a separate .cu file while still keeping the definitions of the template functions inside the template class definition in the header, and adding an #include "file.h" in the file.cu. To solve any link errors with the template function declarations that were moved to a .cu file, an explicit instantiation of the template class was added to the bottom of the header file. Since only float types were used in the template functions using cuda, only an instantiation of type float was added: template class Matrix. The above solution compiled and ran perfectly.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can templates only be implemented in the header file?
What is an undefined reference/unresolved external symbol error and how do I fix it?
I have defined a template class in a file.
point.h is
#ifndef POINT_H
#define POINT_H
using namespace std;
template <typename T, int size>
class point {
private:
T coordinates[size];
public:
point();
void set_coordinates(const T *);
void get_coordinates(T *);
};
#endif /* POINT_H */
point.c is
#include "point.h"
template <typename T, int size>
point::point() {
for (int i = 0; i < size; i++)
coordinates[i] = 0;
}
template <typename T, int size>
void point<T, size>::set_coordinates(const T *coordinates) {
for (int i = 0; i < size; i++)
this->coordinates[i] = coordinates[i];
}
template <typename T, int size>
void point<T, size>::get_coordinates(T *coordinates) {
for (int i = 0; i < size; i++)
coordinates[i] = this->coordinates[i];
}
I am using this template as point<int, 2> p0;. But compiler gives error that point<int, 2> is not defined.
I searched on this and found two solutions -
1. to use export variable. But I read that it is not supported by all compilers. So, I don't want to use that.
2. to create explicit class specializations like
template <> class point<int> {
...
}
But isn't there any other way to do this? (I mean in C++ standard containers, they might have used some technique to do this.)
Read this and the next two FAQ questions - C++ FAQ
The solution of the c++ standard containers is keep everything in the header file.
You should put all the definitions belonging to the template point (that is, including the member functions) to the point.h file and include it in any file that uses the point class, so that the compiler can instantiate it as needed. See this question for details.
The C++ compilers and linkers have means to avoid "multiple definitions" error on link (the ODR rule in the standard states this must be the case).