'Accessing data object form derived class from friend Base class
I am trying out an implementation of Policy based design as below
#include <iostream>
#include <vector>
using uint = unsigned int ;
struct hashing_scheme_base_v;
template <typename T=int,typename hashing_scheme_t=hashing_scheme_base_v>
struct hash_map;
struct hashing_scheme_base_v
{
virtual void allocate(uint value) = 0;
};
struct hashing_scheme_der:public hashing_scheme_base_v
{
template <typename T,typename hashing_scheme_t>
void allocate(uint value)
{
typedef typename hash_map<T,hashing_scheme_t>::data hash_map_data;
hash_map_data[value % hash_map_data.size()] = value;
}
};
template <typename T,typename hashing_scheme_t>
struct hash_map: public hashing_scheme_t
{
std::vector <T> data;
hash_map(int size)
{
data = std::vector <T> (size,-1);
}
friend struct hashing_scheme_der;
};
int main()
{
hash_map <int,hashing_scheme_der> m_hmap(10);
return 0;
}
And I got the following error
**: In member function 'void hashing_scheme_der::allocate(uint)':
../kaufmann/ADTs/divide_and_conquer.cpp:18:28: error: expected ']' before '%' token
18 | hash_map_data[value % hash_map_data.size()] = value;
| ^~
| ]
../kaufmann/ADTs/divide_and_conquer.cpp:18:22: error: structured binding declaration cannot have type 'hash_map_data'
18 | hash_map_data[value % hash_map_data.size()] = value;
| ^
../kaufmann/ADTs/divide_and_conquer.cpp:18:22: note: type must be cv-qualified 'auto' or reference to cv-qualified 'auto'
../kaufmann/ADTs/divide_and_conquer.cpp:18:51: error: declaration of 'auto value' shadows a parameter
18 | hash_map_data[value % hash_map_data.size()] = value;
| ^
../kaufmann/ADTs/divide_and_conquer.cpp: In function 'int main()':
../kaufmann/ADTs/divide_and_conquer.cpp:33:39: error: cannot declare variable 'm_hmap' to be of abstract type 'hash_map<int, hashing_scheme_der>'
33 | hash_map <int,hashing_scheme_der> m_hmap(10);
| ^~~~~~
../kaufmann/ADTs/divide_and_conquer.cpp:22:8: note: because the following virtual functions are pure within 'hash_map<int, hashing_scheme_der>':
22 | struct hash_map: public hashing_scheme_t
| ^~~~~~~~
../kaufmann/ADTs/divide_and_conquer.cpp:10:18: note: 'virtual void hashing_scheme_base_v::allocate(uint)'
10 | virtual void allocate(uint value) = 0;
| ^~~~~~~~
ninja: build stopped: subcommand failed.**
How do I forward declare the base classes to resolve the compile errors I am getting?
Many Thanks!
Edit::
I resolved the error,the design was faulty to begin with. Here's the corrected code
#include <iostream>
#include <vector>
using uint = unsigned int ;
template<typename Derived>
struct hashing_scheme_base_v;
template<typename DataType,typename Derived>
struct removal_scheme_base_v;
/*
template <typename T=int,template <typename > typename hashing_scheme_t=hashing_scheme_base_v>
struct hash_map;*/
template <typename T,template <typename > typename hashing_scheme_t,template <typename ...> typename removal_scheme_t >
struct hash_map;
template<typename Derived>
struct hashing_scheme_base_v
{
virtual void allocate(uint value) = 0;
};
template<typename Derived>
struct hashing_scheme_der:public hashing_scheme_base_v <Derived>
{
void allocate(uint value)
{
static_cast<Derived*>(this)->data[value%static_cast<Derived*>(this)->data.size()] = value;
}
};
// Removal scheme
template<typename DataType,typename Derived>
struct removal_scheme_base_v
{
virtual void remove(DataType value) = 0;
};
template<typename DataType,typename Derived>
struct removal_scheme_der:public removal_scheme_base_v <DataType,Derived>
{
void remove(DataType value)
{
if(static_cast<Derived*>(this)->data[value%static_cast<Derived*>(this)->data.size()] == value)
static_cast<Derived*>(this)->data[value%static_cast<Derived*>(this)->data.size()] = -1;
}
};
template <typename T,template <typename > typename hashing_scheme_t,template <typename... > typename removal_scheme_t >
struct hash_map: public hashing_scheme_t<hash_map <T,hashing_scheme_t,removal_scheme_t>>,removal_scheme_t<T,hash_map <T,hashing_scheme_t,removal_scheme_t>>
{
std::vector <T> data;
hash_map(int size)
{
data = std::vector <T> (size,-1);
}
inline void print()
{
for(auto itr:data)
{
std::cout<<itr<<" ";
}
std::cout<<std::endl;
}
};
int main()
{
hash_map <int,hashing_scheme_der,removal_scheme_der> m_hmap(10);
m_hmap.allocate(3.00);
m_hmap.allocate(5.00);
m_hmap.allocate(17.00);
m_hmap.print();
m_hmap.remove(17.00);
m_hmap.print();
return 0;
}
The above code uses CRTP to access derived class objects in the Base Class,this allows us to use the hash_map class just as an object which holds data and containers and base classes implment the functionality
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
