Error with implement map within template c++ - c++

I need to use a map with various type within es int,int or char,int or char,char....
This is my c++ code:
#include <iostream>
#include<map>
using namespace std;
template< class A, class B >
class MyClass {
private:
std::map<A,B> DatMap;
public:
MyClass<K,T>(){
DatMap = 0;
}
~MyClass(){
delete DatMap;
}
void DatInsert( A k ,B v ) {
DatMap.insert( std::pair<A,B>( k, v) );
}
};
int main(){
DatMap<int,int> datmap1();
diz1.DatInsert();
}
I found this error on: diz1.DatInsert(); line
the error is:
error: request for member ‘DatInsert’ in ‘datmap1’, which is of non-class type ‘DatMap<int, int>()’|
What am I doing wrong?

This is a function declaration:
// functon datamap1, returns DatMap<int, int>
DatMap<int,int> datmap1();
You need
DatMap<int,int> datmap1;
Alternatively, this syntax is valid since C++11
DatMap<int,int> datmap1{};

Vlad and Jauncho make good points but have both missed another error
DatMap<int,int> datmap1(); isn't valid also because there is no public type DatMap exposed. The class is MyClass
You should be saying:
MyClass<int,int> datmap1; // or datmap1{};

There are several errors in the code.
For example identifiers K and T used in this code snippet
MyClass<K,T>(){
DatMap = 0;
}
are undefined. Also the assignment DataMap by zero is invalid.
You shall not delete DatMap in destructor
~MyClass(){
delete DatMap;
}
because DatMap is not a pointer.
These both statements in main
DatMap<int,int> datmap1();
diz1.DatInsert();
are invalid. The first one is a declaration of a function that shall not be compiled. And the second statement contains call of member function DatInsert without arguments. You defined the function as having two parameters
void DatInsert(A k ,B v){
DatMap.insert(std::pair<A,B>(k,v));
}
so you need to provide two arguments.

Related

Initialising a vector of structs containing function pointers gives "no viable overloaded '=' "

I am trying to write a chip CPU emulator and implementing its instruction table as a vector of structs where each struct contains a value and a function pointer to a particular operation. My compiler (clang++) however gives me the error:
no operator "=" matches these operands -- operand types are: std::__1::vector<A::someStruct, std::__1::allocator<A::someStruct>> = {...}
and:
no viable overloaded '='
for the line func_table = {{1,&A::func1},{2,&A::func2}};
I'm using the exact same syntax used in a similar project on GitHub but I still get these errors. It only seems to be a problem initialising with structs of non-null function pointers. I'm very new to programming with C++ so i'd love to know what I'm misunderstanding. Below is an example of the header and source file
#include <vector>
class A{
public:
A();
private:
struct someStruct{
int a = 0;
void (*fptr)(void) = nullptr;
};
std::vector<someStruct> func_table;
void func1();
void func2();
};
#include "tutorial.h"
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}}; // two entries here, but the table is 512 long
}
void A::func1(){
// something
}
void A::func2(){
// something else
}
int main(){
A example;
return 0;
}
I don't understand what these errors mean and why brace initialisation seems to have a problem with function pointers. I would really appreciate any input on this. Thanks
The structure definition should look like
struct someStruct{
int a = 0;
void (A::*fptr)(void) = nullptr;
};
because you are trying to use member functions of the class A as initializers.
A::A(){
func_table = {{1,&A::func1},{2,&A::func2}};
}
That is you have to declare pointers to class members.

Declaration of std::vector works with forward declared classes?

I have a header file like the below -
// abc.hpp
#include <vector>
#include <string>
namespace A
{
namespace B
{
struct abc
{
std::string _type;
};
using abc_vector = std::vector<abc>;
}
}
I am using forward declaration in another header file.
// con.hpp
#include <vector>
namespace A
{
namespace B
{
struct abc; // Forward Declaration
using abc_vector = std::vector<abc>;
}
namespace C
{
class N
{
public:
B::abc_vector foo(std::string type);
};
}
}
What really confuses me is that my code compiles and works.
How is the vector allowed to be declared with incomplete type?
I think that it shouldn't be able to decide the size of abc.
using abc_vector = std::vector<abc>;
The below is the code I used to test my header files.
Strange enough, that it compiles and works all fine.
#include "con.hpp"
#include "abc.hpp"
#include <iostream>
namespace A
{
namespace C
{
B::abc_vector N::foo(std::string type)
{
B::abc a;
a._type = type;
B::abc_vector d;
d.push_back(a);
return d;
}
}
}
int main()
{
A::C::N n;
auto container = n.foo("test");
for (const auto& i : container)
std::cout << i._type << ' ';
return 0;
}
The code line
using abc_vector = std::vector<abc>;
only introduces a type alias for std::vector<abc>. That doesn't require, by any means, the size of abc since no object of type abc is allocated at all. Only a new type is declared.
B::abc_vector d;
Indeed needs the definition of abc. Nevertheless it works because at this point abc already has been defined because the header file abc.hpp has been included.
You are referring to this answer, where
std::vector<B> v;
is "done." This is not the same as what you did. You just introduced a type alias. std::vector<B> v; actually defines a variable. Therefore the definition of B is mandatory.
Note that
using abc_vector = std::vector<abc>;
is equivalent to
typedef std::vector<abc> abc_vector;
Maybe this makes it a bit clearer why the size of abc isn't necessary to know at this time point in compilation.
This is an interesting topic (at least to me) and applies to other std containers.
Originally the standard made it undefined behaviour to instantiate a container of an incomplete type. However implementations did not disallow it. This was in all likelihood not deliberate, but merely a side-effect of the fact that elements in (for example the vector) are stored in a memory location that is referenced by a pointer.
Thus the size of an element does not need to be known until an element is actually required - during the instantiation of a member function of the vector.
Here is a starting point for research if you'd like to explore further:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4056.html
There is an interesting observation. Both GCC5.2 and CLANG3.6 compile following code.
struct A;
std::vector<A> my_func(); //Definition of my_func is in some CPP file
But throw errors for
struct A;
std::vector<A> v;
And reasoning for this is size of vector won't change for different type it is holding. See following code snippet.
struct B{int i; int j;};
struct C{int a,b,c;};
std::vector<B> pp;
std::vector<C> qq;
int main()
{
std::cout<<sizeof(pp)<<'\n';
std::cout<<sizeof(qq)<<'\n';
}
Output
24
24
But for std::vector<A> v it has to provide the Allocator<A>() as well. And allocator required members of struct A like constructor, copy constructor, destructor etc.
Also one important thing to note here is pointer arithmetic for incomplete type is not allowed.
If you see the errors thrown by CLANG, it clearly says same.
In file included from /tmp/gcc-explorer-compiler115920-68-1xsb8x7/example.cpp:2:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/vector:64:
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_vector.h:161:9: error: arithmetic on a pointer to an incomplete type 'A'
- this->_M_impl._M_start); }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/4.9/../../../../include/c++/4.9/bits/stl_vector.h:253:7: note: in instantiation of member function 'std::_Vector_base<A, std::allocator<A> >::~_Vector_base' requested here
vector()
^
Everything else is quite straight forward.
Following is a typedef , so compiler does need to know about size.
using abc_vector = std::vector<abc>;
So, the code structure discussed in question is good to go ahead with.

Error when changing a vector value in a class

I am attempting to change a value in a vector which is a variable in a class using a function of a class. When I compile, i get the following errors pointing to the "check[c] = cval;" line:
error C3867: 'acc::check': function call missing argument list; use '&acc::check' to create a pointer to member
error C2109: subscript requires array or pointer type
Note: I have already initialized C to be 0 elsewhere in the program. It might be throwing an error because I am giving the address a variable instead of an integer, but when I substitute the variable with an integer, I still get the same errors.
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <cstring>
using namespace std;
class acc
{
public:
void add_Cval(double cval);
private:
vector<double> check(); //vector of all checks
int c; //loop marker for cvals
};
void acc::add_Cval(double cval)
{
check[c] = cval;
c++;
}
vector<double> check(); isn't what you think it is. You just declared a function named check that returns a vector<double>. Get rid of the parenthesis like so vector<double> check;.
Also, your vector<double> is empty, you need to give it some space if you want to do check[c] = cval; (or use check.push_back(cval); instead), allocate the space in the constructor (use "initialization lists" as that is what they are for):
Example:
acc(int vecsize) : check(vecsize), c(0) {}
You might also want to make sure check[c] is a valid position in the vector before assigning anything to it.
check is a method, not a data member, so you need to invoke it - check().
void acc::add_Cval(double cval)
{
check()[c] = cval;
c++;
}
or make it a data member:
class acc
{
public:
void add_Cval(double cval);
private:
vector<double> check; //vector of all checks
int c; //loop marker for cvals
};
The compiler is looking for a function called check() that returns a vector of type double.
private:
vector<double> check(); // A private function that returns a vector of type <double>
Needs to be:
private:
vector<double> check; // A private data member

Calling C++ member function pointer from a struct

I have found information on calling C++ member function pointers and calling pointers in structs, but I need to call a member function pointer that exists inside of a structure, and I have not been able to get the syntax correct. I have the following snippet inside a method in class MyClass:
void MyClass::run() {
struct {
int (MyClass::*command)(int a, int b);
int id;
} functionMap[] = {
{&MyClass::commandRead, 1},
{&MyClass::commandWrite, 2},
};
(functionMap[0].MyClass::*command)(x, y);
}
int MyClass::commandRead(int a, int b) {
...
}
int MyClass::commandWrite(int a, int b) {
...
}
This gives me:
error: expected unqualified-id before '*' token
error: 'command' was not declared in this scope
(referring to the line '(functionMap[0].MyClass::*command)(x, y);')
Moving those parenthesis around results in syntax errors recommending using .* or ->* neither of which work in this situation. Does anyone know the proper syntax?
Use:
(this->*functionMap[0].command)(x, y);
Tested and compiles ;)
I haven't compiled any code, but just from looking at it I can see you're missing a few things.
Remove the MyClass:: from where you call the function pointer.
Need to pass the this pointer to the functions (if they use any instance data), so that means you need an instance of MyClass to call it.
(After a bit of research) It looks like you need to do something like this (also thanks to #VoidStar):
(this->*(functionMap[0].command)(x, y));

Calling the function pointed by a Pointer-to-Member-Function from within a struct

I have a class Test with a peculiar data structure.
A member of class Test is a std::map where the key is a std::string and the mapped value is a struct defined as follows:
typedef struct {
void (Test::*f) (void) const;
} pmf_t;
Initialization of the map is OK. The problem is when I am trying to call the function pointed. I made up a toy example reproducing the problem. Here it is:
#include <iostream>
#include <map>
using namespace std;
class Test;
typedef void (Test::*F) (void) const;
typedef struct {
F f;
} pmf_t;
class Test
{
public:
Test () {
pmf_t pmf = {
&Test::Func
};
m["key"] = pmf;
}
void Func (void) const {
cout << "test" << endl;
}
void CallFunc (void) {
std::map<std::string, pmf_t>::iterator it = m.begin ();
((*it).second.*f) (); // offending line
}
std::map<std::string, pmf_t> m;
};
int main ()
{
Test t;
t.CallFunc ();
return 0;
}
Thanks in advance,
Jir
The name of the pmf_t type is f, so the first change is to remove the * to get second.f. That gives you a pointer-to-member value. To use a pointer-to-member, you need an instance. The only one you have available of the correct type is this, so use it with the ->* operator:
(this->*it->second.f)();
You need parentheses around the whole thing, or else the compiler thinks you're trying to call it->second.f() (which isn't allowed) and then applying the result to ->*.
The offending line is trying to call a member function without any object to call it on. If the intention is to call it for the this object, I believe the call should look like
( this->* ((*it).second.f) )();
Where this->* is the syntax for dereferencing a pointer-to-member for the current object. ((*it).second.f) is the pointer retrieved from the map, and () is the call operator for actually calling the function.
This is perhaps good as an exercise, but otherwise of limited use.
I think you might want to check out the C++ FAQ on this one. The syntax is apparently pretty tricky to get right (they actually recommend using a macro).
It might be too late for this question but, the seemingly complex synatax can be break down to two simple lines so it looks pretty clear:
void CallFunc (void)
{
pmf_t t = m["key"]; //1>get the data from key
(this->*t.f)(); //2>standard procedure to call pointer to member function
}
try this:
(this->*((*it).second.f)) ();