i have a stucture:
template <class T> struct Array{
int days;
T * M;
Array( int size ) : days(size), M(new T[size])
{
}
~Array()
{
delete[] M;
}
};
void currentDay();
void add(int,int,Array &);
and a class:
class Expe {
private:
int hk; //HouseKeeping
int fo; //Food
int tr; //Transport
int cl; //Clothing
int tn; //TelNet
int ot; //Others
}
Class contructor is :
Expe::Expe() {
this->hk = hk;
this->fo = fo;
this->tr = tr;
this->cl = cl;
this->tn = tn;
this->ot = ot;
}
THE PROBLEM: in main function i can manipulate the structure with objects... using the setObj() function for example but when i try to define my functions in Controller or in Controller.h i get the fallowing error:
..\ListStruc.cpp:28:28: error: 'Array' is not a type
..\ListStruc.cpp: In function 'void add(int, int, int)':
..\ListStruc.cpp:31:4: error: request for member 'M' in 'A', which is of non-class type 'int'
EDIT:
void add(int cant, int tip,Array A){
//Adds to current day the amount to a specific type
A.M[currentDay]; // i try to use this object.
}
This declaration is incorrect:
void add(int,int,Array &);
Since Array is a class template, the add function needs to be a template as well:
template <class T>
void add(int,int,Array<T> &);
Additionally, your definition of the add function takes the parameter by value, while the declaration takes the parameter by reference.
Related
[Solved]: The problem was not in template class initialization, but with code-specific issue of using undefined macro inside a template class constructor. The compiler error did not complain about undefined symbol, but was (wrongfully) related to lambdas.
I've searched for an answer but couldn't find an exact one. The closest answer is here: C++ invoke explicit template constructor but I'm not sure if that is entirely related to my question.
And my question is, how can I initialize a member of structure B in initialization list if the member is a template class?
Header ClassA.h:
#ifndef _A_
#define _A_
#include <typeinfo>
#include <windows.h>
template<class Type> class A{
int u,v;
Type** pointer;
public:
A();
A(int number);
~A();
Type& operator[] (int i){
typeid(Type);
return *pointer[i];
}
Type& Get(int i)
{
typeid(Type);
return *pointer[i];
}
Type *GetPointer(int i)
{
typeid(Type);
return pointer[i];
}
Type* add ();
Type& add(Type *element);
Type& add(Type *element, int place);
void expand(int NewLength);
void swap(Type *element, int place);
void remove(int number);
void remove(Type *element);
void removePointer(int number);
void removePointer(Type *element);
};
template<class Type>A<Type>::A(){
u = 128;
v = 10;
}
template<class Type>A<Type>::A(int number){
//some thing to do with number;
u = number;
v = 10;
New( pointer, Type *[u] );
}
template <class Type> A<Type>::~A()
{
}
template <class Type> void A<Type>::expand(int NewLength)
{
Type **NewList = NULL;
NewList = new Type*[NewLength];
}
template <class Type> Type* A<Type>::add ()
{
pointer[u] = new Type;
}
template <class Type> Type& A<Type>::add(Type *element)
{
}
template <class Type> Type& A<Type>::add(Type *element, int place)
{
}
template <class Type> void A<Type>::swap(Type *element, int place)
{
}
template <class Type> void A<Type>::remove(Type *element)
{
}
template <class Type> void A<Type>::removePointer(int nume)
{
}
template <class Type> void A<Type>::removePointer(Type *element)
{
}
#endif
Header StructB.h:
#pragma once
#ifndef _B_
#define _B_
#include "ClassA.h"
struct C{
float x,y,z;
};
struct B{
private:
B(){
}
public:
int x,y;
A<B*> member1;
A<C> member2;
B(int X,int Y) : member1(5),member2(5) {
//initialize x,y
}
void Add(B* otherB){
B** _pOtherB = new B*; (*_pOtherB) = otherB;
member1.add(_pOtherB);
}
};
#endif
The compiler complains with this error (and some other errors, I can post them if nedded):
error C3493: 'number' cannot be implicitly captured because no default capture mode has been specified
Is there any way to do this, or some workaround perhaps?
Thanks in advance :D
Either the code you've given us isn't complete, or it is broken. This line:
New(pointer, Type *[u]);
seems to be referencing either some missing member method or global function, or it is simply invalid. The error message is kinda cryptic, but that's C++ for you.
I'm going to assume that New is some kind of macro, because no normal function (even a templated one) can take this sort of type definition as a parameter. You've not given us the definition of New, so there's no way we can tell. It is probably the absense of this macro (maybe a wrapper for some sort of memory debugging system?) that is causing the crazy error.
If I replace the New line with this:
pointer = new Type*[u];
the code compiles fine.
I've searched through Google and stackoverflow and was unable to find something that addresses this situation:
I have a template with a method that takes a function pointer.
The function pointer itself is NOT a template, it's a normal function pointer.
The function pointer, however, has the template args used in its parameters
File name: otherclasses.h
// This class is used as the template parameter
class B
{
public:
B() {}
~B() {}
int getVal() const { return val; }
void setVal(int v) { val = v; }
private:
int val;
};
// This is just a static function
class A
{
public:
static bool someStaticFunction(const B* left, const B* right);
};
inline
bool
A::someStaticFunction(
const B* left,
const B* right)
{
return left->getVal() < right->getVal();
}
File name: templateheader.h
#include "otherclasses.h"
template<typename T>
class theTemplate
{
public:
void insert(T val1, T val2)
{
stuff[0] = val1;
stuff[1] = val2;
}
bool usesSomeStaticFunction(bool (*funcp)(const T, const T))
{
// will return true
return funcp(stuff[0],stuff[1]);
}
private:
T stuff[2];
};
File name: main.cpp
#include "otherclasses.h"
#include "templateheader.h"
#include <stdio.h>
int main()
{
theTemplate<B*> foo;
printf("%d\n", foo.usesSomeStaticFunction(A::someStaticFunction));
return 0;
}
The error from Visual Studio:
error C2664: 'theTemplate<T>::usesSomeStaticFunction' : cannot convert
parameter 1 from 'bool (__cdecl *)(const B *,const B *)' to
'bool (__cdecl *)(const T,const T)'
with
[
T=B *
]
None of the functions with this name in scope match the target type
Two ways around this problem:
Use const void* instead of const T*
Remove const from the parameters of the function pointer and anything that uses it.
Thanks for your help
UPDATE
Turns out there's a better solution - just move the const to the right of B* in the static function:
File name: otherclasses.h EDITED
// This class is used as the template parameter
// This is unchanged.
class B
{
public:
B() {}
~B() {}
int getVal() const { return val; }
void setVal(int v) { val = v; }
private:
int val;
};
// This is just a static function
// This is changed
class A
{
public:
// The "const" is moved to the right side of B*
static bool someStaticFunction(B* const left, B* const right);
};
// This is changed
inline
bool
A::someStaticFunction(
// The function definition must match the function prototype...
B* const left,
B* const right)
{
return left->getVal() < right->getVal();
}
This is because const T becomes T* const, not T const*. One solution is to rework your code to not include the pointer in T (T = B) and include it in the template class instead:
template<typename T>
class theTemplate
{
public:
void insert(T* val1, T* val2)
{
stuff[0] = val1;
stuff[1] = val2;
}
bool usesSomeStaticFunction(bool (*funcp)(const T*, const T*))
{
// will return true
return funcp(stuff[0],stuff[1]);
}
private:
T* stuff[2];
};
I have a hash table template that I have written for a class. I have a project due that relies on utilizing this hash table. It accepts an unsigned integer value to initialize the number of buckets it has, as well as a hash function to point to. I have not written that hash function yet, but I have a declaration for it. When I try to use the member initializer in my Game class for the hash table data member, it gives me an error that I don't understand.
Error 1 error C3867: 'Game::xorHash': function call missing argument list; use '&Game::xorHash' to create a pointer to member
2 IntelliSense: no instance of constructor "HTable<Type>::HTable [with Type=std::string]" matches the argument list
argument types are: (int, unsigned int (const std::string &s))
my Hash Table class is as follows:
#pragma once
#include "SLList.h"
template<typename Type> class HTable
{
public:
HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v));
~HTable();
HTable<Type>& operator=(const HTable<Type>& that);
HTable(const HTable<Type>& that);
void insert(const Type& v);
bool findAndRemove(const Type& v);
void clear();
int find(const Type& v) const;
private:
SLList<Type>* ht;
unsigned int (*hFunct) (const Type &v);
unsigned int numOfBuck;
};
template<typename Type>
HTable<Type>::HTable(unsigned int numOfBuckets, unsigned int (*hFunction) (const Type &v))
{
ht = new SLList<Type>[numOfBuckets];
this->numOfBuck = numOfBuckets;
this->hFunct = hFunction;
}
template<typename Type>
HTable<Type>::~HTable()
{
delete [] ht;
ht = nullptr;
}
template<typename Type>
HTable<Type>& HTable<Type>::operator=(const HTable<Type>& that)
{
if(this != &that)
{
delete [] this->ht;
this->hFunct = that.hFunct;
this->numOfBuck = that.numOfBuck;
this->ht = new SLList<Type>[numOfBuck];
for(unsigned int i = 0; i < this->numOfBuck; i++)
this->ht[i] = that.ht[i];
}
return *this;
}
template<typename Type>
HTable<Type>::HTable(const HTable<Type>& that)
{
this = *that;
}
template<typename Type>
void HTable<Type>::insert(const Type& v)
{
ht[hFunct(v)].addHead(v);
}
template<typename Type>
bool HTable<Type>::findAndRemove(const Type& v)
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
{
ht[hFunct(v)].remove(iter);
return true;
}
}
return false;
}
template<typename Type>
void HTable<Type>::clear()
{
for(unsigned int i = 0; i < this->numOfBuck; ++i)
ht[i].clear();
}
template<typename Type>
int HTable<Type>::find(const Type& v) const
{
SLLIter<Type> iter(ht[hFunct(v)]);
for(iter.begin(); !iter.end(); ++iter)
{
if(v == iter.current())
return hFunct(v);
}
return -1;
}
My Game.h:
#pragma once
#include "stdafx.h"
#include "HTable.h"
#include "BST.h"
#include "DTSTimer.h"
using namespace std;
class Game
{
public:
Game(void);
virtual ~Game(void);
void refresh();
void input();
unsigned int xorHash(const string &s);
private:
string userInput;
DTSTimer timer;
BST<string> answers;
HTable<string> dictionary;
};
My Game.cpp (this is obviously just a skeleton, since I can't get the member init to work)
#include "Game.h"
Game::Game(void) : dictionary(2048, xorHash)
{
}
Game::~Game(void)
{
}
void Game::refresh()
{
}
void Game::input()
{
}
unsigned int Game::xorHash(const string &s)
{
return 0;
}
I've been working on this for a good while, and have been hitting a wall. I would really appreciate some help on how to get this thing up and running. Let me know if there is another snippet that needs to be seen (I've tried to be thorough in that regard).
You have two problems. The first is that you don't pass the member function pointer properly (the error message tells you exactly what do do). The other problem is that a function pointer is not the same as a member function pointer.
A member function pointer needs an instance object object to call the member function on. And this instance is passed as a hidden first argument, something that normal functions don't have.
For this you might instead turn to std::function and std::bind:
class HTable
{
public:
HTable(unsigned int numOfBuckets, std::function<unsigned int(const Type&)> hFunction);
...
private:
std::function<unsigned int(const Type&)> hFunct;
...
};
Then
Game::Game(void) : dictionary(2048, std::bind(&Game::xorHash, this))
{
}
I'm trying to declare an object of type WRAPPED that is within the class WRAPPED and the class WRAPPED is contained within another class called WRAPPER. I'm getting these compiler errors.
nested_class_incomplete_type.cpp|56|instantiated from 'WRAPPER<NODE>'|
nested_class_incomplete_type.cpp|62|instantiated from here|
nested_class_incomplete_type.cpp|36|error: 'WRAPPER<T>::WRAPPED::WRAP' has incomplete type|
nested_class_incomplete_type.cpp|33|error: declaration of 'class WRAPPER<NODE>::WRAPPED'|
I tried doing this too WRAPPER::WRAPPED WRAP; but that yields the same exact error. This normally would not be an issue if the WRAPPED class existed outside a class but for some reason it won't allow me to declare such a simple object. Feel free to enlighten me with the magical world of C++ compiler semantics and the god Stroustrup. Heres the code.
#include <iostream>
using namespace std;
class NODE
{
int data;
public:
NODE(){}
~NODE(){}
NODE(int data)
{
this->data = data;
}
void print()
{
std::cout<<"data: "<<this->data<<std::endl;
}
};
template <class T>
class WRAPPER
{
public:
static T GLOBAL_WRAPPER_TYPE;
WRAPPER(){}
~WRAPPER(){}
class WRAPPED
{
public:
WRAPPER::WRAPPED WRAP;
WRAPPED(){}
~WRAPPED(){}
void set(T GLOBAL_WRAPPER_TYPE)
{
WRAPPER::GLOBAL_WRAPPER_TYPE = GLOBAL_WRAPPER_TYPE;
}
T& get()
{
return GLOBAL_WRAPPER_TYPE;
}
WRAPPED& operator=(const WRAPPED &INSIDE)
{
GLOBAL_WRAPPER_TYPE = INSIDE.GLOBAL_WRAPPER_TYPE;
return *this;
}
};
WRAPPED INSIDE;
};
template <class T>
T WRAPPER<T>::GLOBAL_WRAPPER_TYPE;
int main()
{
WRAPPER<NODE> WRAPPING;
WRAPPING.INSIDE.set(NODE(99));
NODE temp = WRAPPING.INSIDE.get();
temp.print();
return 0;
}
Essentially what you're trying to do is:
class A
{
A a;
};
int main()
{
A a;
return 0;
}
(You can see that this produces the same error here)
This is infinite recursion, you're defining a type using itself. Take a pointer instead, like so:
class A
{
A* a;
};
int main()
{
A a;
return 0;
}
As you can see here this compiles.
the fallowing code tells me that o.days and days from constructor can't be solved, has anyone an idea why?
template <class T> struct Array{
int days;
T * M;
};
contructor of the class:
void constr(Array<Expe> &o){
o=new Array;
o->days = days;
o->M = new Array[o->days];
}
EDIT (Luchian Grigore):
template <class T> struct Array{
int days;
T * M;
Array( int size ) : days(size), M(new int[size])
{
}
~Array()
{
delete[] M;
}
};
when i try to init an array in main like this:
int main(){
//Main function of the program. no pre/ post condition.
Array <Expe> A;
error:
enter code here..\M.cpp:18:15: error: no matching function for call to 'Array::Array()'
Array<Expe> &o is a reference to an Array<Expe> object, not a pointer. If you must re-initialize it, the syntax is.
o = Array<Expe>();
and you access the members via .:
o.days = days;
o.M = new Array[o.days];
EDIT:
I remember the same code from yesterday. Why are you agains using proper constructors?
template <class T> struct Array{
int days;
T * M;
Array( int size ) : days(size), M(new int[size])
{
}
~Array()
{
delete[] M;
}
};