How to access and manage block stored data - c++

What I want to do: I need to store cell data in block-wise form, that is
*cell_member1[cell0] .. cell_member1[cellN] ... cell_memberM[cell0] .. cell_memberM[cellN]*
Then I need to access this data efficiently and, if possible, using a nice syntax. It would be great if I could define the data to be stored easily, i.e. by defining an object with members as the data that I want to store and passing it to some "magic" that does everything for me.
Motivation: why I need to do it this way? Cache trashing. In some inner loops only some members of the objects are accessed. Wasting half of a cache-line with unused memory is not an option for my application. I could store pointers in the objects that point to some sequential memory region. This wastes memory and forces me to use a different syntax in this regions.
How I'm currently doing it: I have a container of the form:
template<class T> struct Container {
char* data;
Container(const int n) {
data = new char[n*T::spaceRequirements()]; //< Data stored "block-wise"
new(data) typename T::Flags[n]; //< Flags stored "cell-wise"
}
/// Destructor ommited for briefness.
};
in which I store data for some cells of type T. I need some flags per cell and right now I'm using std::bitset to store them which means that I need to store this bitsets in cell-wise form:
*cell_member1[cell0] ... cell_memberM[cell0] ... cell_member1[cellN] .. cell_memberM[cellN]*
I am describing how much data per cell needs to be stored in the following class, which also provides access to the data:
template<int nd> struct CellAccessor {
/// Cell flags are stored cell-wise:
typedef std::bitset<64> Flags;
enum { DELETE = 0, ///< Cell marked for deletion
REFINE = 1 ///< Cell marked for refinement
//...
}; ///< Enum for the flags.
static inline Flags& flags(const int cellId) {
return *reinterpret_cast<Flags*>(data + sizeof(Flags)*cellId); }
template<int pId> static inline Flags::reference flags(const int cellId) {
return flags(cellId)[pId]; } //< Cell-wise access to the properties
/// The rest of the data is stored block-wise:
static inline int& order(const int cellId) { ///< One int field.
return *reinterpret_cast<int*>
(data + maxNoCells*sizeof(Flags) + sizeof(int)*cellId);}
/// Coordinate vector with nd components:
static inline double& coordinates(const int cellId, const int i) {
return *reinterpret_cast<double*>
(data + maxNoCells*(sizeof(Flags)+sizeof(int))
+ maxNoCells*i*sizeof(double) + sizeof(double)*cellId); }
template<int i> static inline double& coordinates(const int cellId) {
return *reinterpret_cast<double*>
(data +maxNoCells*(sizeof(Flags)+sizeof(int)+i*sizeof(double))
+ sizeof(double)*cellId); }
/// Total amount of memory to allocate per cell: (used by Container)
static inline int spaceRequirements() { return
sizeof(Flags) // Flags
+ sizeof(int) // order
+ nd*sizeof(double) // coordinates
;}
/// Constructor gets pointer to the beginning of the container
/// and the offset for the member variables:
CellAccessor(char* d, int n){data = d; maxNoCells = n;}
private:
static char* data; ///< Pointer to the beginning of the container.
static int maxNoCells; ///< Cell offset for the member variables.
};
template<int nd> char* CellAccessor<nd>::data = nullptr;
template<int nd> int CellAccessor<nd>::maxNoCells = 0;
And I use it like this:
int main() {
int maxNoCells = 10000; ///< Maximum number of cells (=cell offset).
typedef CellAccessor<2> A;
Container< A > cellData(maxNoCells); ///< Allocate cell data.
A cells(cellData.data,maxNoCells); ///< Provides access to cell data.
for(int i = 0; i < maxNoCells; ++i){
cells.flags<A::DELETE>(i) = i%2==0 ? true : false;
cells.flags<A::REFINE>(i) = i%2==0 ? false : true;
cells.coordinates(i,0) = i;
cells.coordinates<1>(i) = -((double)i);
cells.order(i) = 2;
}
}
Pros:
The data is in block-wise form, which is what I needed.
The syntax is ok.
Problems:
My classes are doing too much: providing access to the data for the users, providing how much data needs to be stored for the containers, providing how the data should be moved/copied/swaped for my data structures (which are trees...)...
I can't use STL algorithms without iterators. I've implemented iterators by making them store the cell index and reimplementing the CellAccessor class inside them (bad! DRY!).
Bitset is still being stored in cell-wise form. I could re-implement bitset for my block-wise data structure...
data and maxNoCells are static variables, but I could make them normal member variables if required.
Question: is there any efficient way to store "objects" (or what we conceptually understand by objects) in block-wise form and access them as if they were stored in a std container such as vector?

What you want is a style of a "COLUMN BASED" memory access
You can easily implement it using std::vector as your column type or create your own "column" type with your own underlying memory management - but std::vector should work just fine
Now once you have your column type you create your "TABLE" type.
In a way your table cab be just a vector of vectors. You can of course wrap it up in order to get better looking accessors (If you want to access by row (object) first and column (property) after.
This is I think the best general approach.
Even In your specific case - since you want to save memory using bit length flags, as mentioned by Bart van Ingen Schenau you can use a vector<bool> so the general approach stands

I would use parrallel arrays to meet the requirements:
template <int nd>
class CellAccessor {
public:
enum { DELETE = 0, ///< Cell marked for deletion
REFINE = 1, ///< Cell marked for refinement
//...
NUM_FLAGS
}; ///< Enum for the flags.
CellAccessor(int numCells) {
for (int i=0; i<NUM_FLAGS; i++) { m_flags[i] = new bool[numCells]; }
m_order = new int[numCells];
for (int i=0; i<nd; i++) { m_coordinates[i] = new double[numCells]; }
}
// Destructor, copy-constructor & assignment operator omitted for brevity
template<int F> inline bool& flags(const int cellId) {
return m_flags[F][cellId]; }
inline bool& flags(const int cellId, int flag) {
return m_flags[flag][cellId]; }
inline int& order(const int cellId) {
return m_order[cellId]; }
template<int i> inline double& coordinates(const int cellId) {
return m_coordinates[i][cellId]; }
inline double& coordinates(const int cellId, int i) {
return m_coordinates[i][cellId]; }
private:
bool* m_flags[NUM_FLAGS];
int* m_order;
double* m_coordinates[nd];
};

Not sure that understood correctly the question. It looks like you are trying to allocate data in a sequential array of bytes. Why?
but in any case you could do it simply by using arrays:
class Cell {
std::bitset<64> flags;
int order;
double coordinates[2];
}
int main() {
const int maxNoCells = 10000;
Cell cells[maxNoCells];
for(int i = 0; i < maxNoCells; i++) {
cells[i].flags = ...;
cells[i].coordinates[0] = i;
cells[i].coordinates[1] = -i;
cells[i].order=2;
}
}
and then cast it to (char *)cells if needed. Your classes will be allocated in a segmented fashion in a contiguous memory strip. You could use it for read/write/net. The only issue is that you have to take care of 32/64 bit alignments in particular if it is
shared between different architectures.
Here is another version which would be a bit better for caching if you insist on using different fields in separate loops:
template<int size>
class CellAccessor {
std::bitset<64> flags[size];
int order[size];
double coordinates[size][2];
public:
std::bitset<64> &getFlags(int id) {
return flags[id];
}
int &getOrder(int id) {
return order[id];
}
...
}
main() {
CellAccessor<10000> ca;
for(...i++) {
ca.getOrder(i) = 2;
ca.getCoordinates(i)[0] = i;
...
}
}

Related

Passing pointer to method into template class [duplicate]

I came across this strange code snippet which compiles fine:
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
return 0;
}
Why does C++ have this pointer to a non-static data member of a class? What is the use of this strange pointer in real code?
It's a "pointer to member" - the following code illustrates its use:
#include <iostream>
using namespace std;
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
Car c1;
c1.speed = 1; // direct access
cout << "speed is " << c1.speed << endl;
c1.*pSpeed = 2; // access via pointer to member
cout << "speed is " << c1.speed << endl;
return 0;
}
As to why you would want to do that, well it gives you another level of indirection that can solve some tricky problems. But to be honest, I've never had to use them in my own code.
Edit: I can't think off-hand of a convincing use for pointers to member data. Pointer to member functions can be used in pluggable architectures, but once again producing an example in a small space defeats me. The following is my best (untested) try - an Apply function that would do some pre &post processing before applying a user-selected member function to an object:
void Apply( SomeClass * c, void (SomeClass::*func)() ) {
// do hefty pre-call processing
(c->*func)(); // call user specified function
// do hefty post-call processing
}
The parentheses around c->*func are necessary because the ->* operator has lower precedence than the function call operator.
This is the simplest example I can think of that conveys the rare cases where this feature is pertinent:
#include <iostream>
class bowl {
public:
int apples;
int oranges;
};
int count_fruit(bowl * begin, bowl * end, int bowl::*fruit)
{
int count = 0;
for (bowl * iterator = begin; iterator != end; ++ iterator)
count += iterator->*fruit;
return count;
}
int main()
{
bowl bowls[2] = {
{ 1, 2 },
{ 3, 5 }
};
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::apples) << " apples\n";
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::oranges) << " oranges\n";
return 0;
}
The thing to note here is the pointer passed in to count_fruit. This saves you having to write separate count_apples and count_oranges functions.
Another application are intrusive lists. The element type can tell the list what its next/prev pointers are. So the list does not use hard-coded names but can still use existing pointers:
// say this is some existing structure. And we want to use
// a list. We can tell it that the next pointer
// is apple::next.
struct apple {
int data;
apple * next;
};
// simple example of a minimal intrusive list. Could specify the
// member pointer as template argument too, if we wanted:
// template<typename E, E *E::*next_ptr>
template<typename E>
struct List {
List(E *E::*next_ptr):head(0), next_ptr(next_ptr) { }
void add(E &e) {
// access its next pointer by the member pointer
e.*next_ptr = head;
head = &e;
}
E * head;
E *E::*next_ptr;
};
int main() {
List<apple> lst(&apple::next);
apple a;
lst.add(a);
}
Here's a real-world example I am working on right now, from signal processing / control systems:
Suppose you have some structure that represents the data you are collecting:
struct Sample {
time_t time;
double value1;
double value2;
double value3;
};
Now suppose that you stuff them into a vector:
std::vector<Sample> samples;
... fill the vector ...
Now suppose that you want to calculate some function (say the mean) of one of the variables over a range of samples, and you want to factor this mean calculation into a function. The pointer-to-member makes it easy:
double Mean(std::vector<Sample>::const_iterator begin,
std::vector<Sample>::const_iterator end,
double Sample::* var)
{
float mean = 0;
int samples = 0;
for(; begin != end; begin++) {
const Sample& s = *begin;
mean += s.*var;
samples++;
}
mean /= samples;
return mean;
}
...
double mean = Mean(samples.begin(), samples.end(), &Sample::value2);
Note Edited 2016/08/05 for a more concise template-function approach
And, of course, you can template it to compute a mean for any forward-iterator and any value type that supports addition with itself and division by size_t:
template<typename Titer, typename S>
S mean(Titer begin, const Titer& end, S std::iterator_traits<Titer>::value_type::* var) {
using T = typename std::iterator_traits<Titer>::value_type;
S sum = 0;
size_t samples = 0;
for( ; begin != end ; ++begin ) {
const T& s = *begin;
sum += s.*var;
samples++;
}
return sum / samples;
}
struct Sample {
double x;
}
std::vector<Sample> samples { {1.0}, {2.0}, {3.0} };
double m = mean(samples.begin(), samples.end(), &Sample::x);
EDIT - The above code has performance implications
You should note, as I soon discovered, that the code above has some serious performance implications. The summary is that if you're calculating a summary statistic on a time series, or calculating an FFT etc, then you should store the values for each variable contiguously in memory. Otherwise, iterating over the series will cause a cache miss for every value retrieved.
Consider the performance of this code:
struct Sample {
float w, x, y, z;
};
std::vector<Sample> series = ...;
float sum = 0;
int samples = 0;
for(auto it = series.begin(); it != series.end(); it++) {
sum += *it.x;
samples++;
}
float mean = sum / samples;
On many architectures, one instance of Sample will fill a cache line. So on each iteration of the loop, one sample will be pulled from memory into the cache. 4 bytes from the cache line will be used and the rest thrown away, and the next iteration will result in another cache miss, memory access and so on.
Much better to do this:
struct Samples {
std::vector<float> w, x, y, z;
};
Samples series = ...;
float sum = 0;
float samples = 0;
for(auto it = series.x.begin(); it != series.x.end(); it++) {
sum += *it;
samples++;
}
float mean = sum / samples;
Now when the first x value is loaded from memory, the next three will also be loaded into the cache (supposing suitable alignment), meaning you don't need any values loaded for the next three iterations.
The above algorithm can be improved somewhat further through the use of SIMD instructions on eg SSE2 architectures. However, these work much better if the values are all contiguous in memory and you can use a single instruction to load four samples together (more in later SSE versions).
YMMV - design your data structures to suit your algorithm.
You can later access this member, on any instance:
int main()
{
int Car::*pSpeed = &Car::speed;
Car myCar;
Car yourCar;
int mySpeed = myCar.*pSpeed;
int yourSpeed = yourCar.*pSpeed;
assert(mySpeed > yourSpeed); // ;-)
return 0;
}
Note that you do need an instance to call it on, so it does not work like a delegate.
It is used rarely, I've needed it maybe once or twice in all my years.
Normally using an interface (i.e. a pure base class in C++) is the better design choice.
IBM has some more documentation on how to use this. Briefly, you're using the pointer as an offset into the class. You can't use these pointers apart from the class they refer to, so:
int Car::*pSpeed = &Car::speed;
Car mycar;
mycar.*pSpeed = 65;
It seems a little obscure, but one possible application is if you're trying to write code for deserializing generic data into many different object types, and your code needs to handle object types that it knows absolutely nothing about (for example, your code is in a library, and the objects into which you deserialize were created by a user of your library). The member pointers give you a generic, semi-legible way of referring to the individual data member offsets, without having to resort to typeless void * tricks the way you might for C structs.
It makes it possible to bind member variables and functions in the uniform manner. The following is example with your Car class. More common usage would be binding std::pair::first and ::second when using in STL algorithms and Boost on a map.
#include <list>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
class Car {
public:
Car(int s): speed(s) {}
void drive() {
std::cout << "Driving at " << speed << " km/h" << std::endl;
}
int speed;
};
int main() {
using namespace std;
using namespace boost::lambda;
list<Car> l;
l.push_back(Car(10));
l.push_back(Car(140));
l.push_back(Car(130));
l.push_back(Car(60));
// Speeding cars
list<Car> s;
// Binding a value to a member variable.
// Find all cars with speed over 60 km/h.
remove_copy_if(l.begin(), l.end(),
back_inserter(s),
bind(&Car::speed, _1) <= 60);
// Binding a value to a member function.
// Call a function on each car.
for_each(s.begin(), s.end(), bind(&Car::drive, _1));
return 0;
}
You can use an array of pointer to (homogeneous) member data to enable a dual, named-member (i.e. x.data) and array-subscript (i.e. x[idx]) interface.
#include <cassert>
#include <cstddef>
struct vector3 {
float x;
float y;
float z;
float& operator[](std::size_t idx) {
static float vector3::*component[3] = {
&vector3::x, &vector3::y, &vector3::z
};
return this->*component[idx];
}
};
int main()
{
vector3 v = { 0.0f, 1.0f, 2.0f };
assert(&v[0] == &v.x);
assert(&v[1] == &v.y);
assert(&v[2] == &v.z);
for (std::size_t i = 0; i < 3; ++i) {
v[i] += 1.0f;
}
assert(v.x == 1.0f);
assert(v.y == 2.0f);
assert(v.z == 3.0f);
return 0;
}
One way I've used it is if I have two implementations of how to do something in a class and I want to choose one at run-time without having to continually go through an if statement i.e.
class Algorithm
{
public:
Algorithm() : m_impFn( &Algorithm::implementationA ) {}
void frequentlyCalled()
{
// Avoid if ( using A ) else if ( using B ) type of thing
(this->*m_impFn)();
}
private:
void implementationA() { /*...*/ }
void implementationB() { /*...*/ }
typedef void ( Algorithm::*IMP_FN ) ();
IMP_FN m_impFn;
};
Obviously this is only practically useful if you feel the code is being hammered enough that the if statement is slowing things done eg. deep in the guts of some intensive algorithm somewhere. I still think it's more elegant than the if statement even in situations where it has no practical use but that's just my opnion.
Pointers to classes are not real pointers; a class is a logical construct and has no physical existence in memory, however, when you construct a pointer to a member of a class it gives an offset into an object of the member's class where the member can be found; This gives an important conclusion: Since static members are not associated with any object so a pointer to a member CANNOT point to a static member(data or functions) whatsoever
Consider the following:
class x {
public:
int val;
x(int i) { val = i;}
int get_val() { return val; }
int d_val(int i) {return i+i; }
};
int main() {
int (x::* data) = &x::val; //pointer to data member
int (x::* func)(int) = &x::d_val; //pointer to function member
x ob1(1), ob2(2);
cout <<ob1.*data;
cout <<ob2.*data;
cout <<(ob1.*func)(ob1.*data);
cout <<(ob2.*func)(ob2.*data);
return 0;
}
Source: The Complete Reference C++ - Herbert Schildt 4th Edition
Here is an example where pointer to data members could be useful:
#include <iostream>
#include <list>
#include <string>
template <typename Container, typename T, typename DataPtr>
typename Container::value_type searchByDataMember (const Container& container, const T& t, DataPtr ptr) {
for (const typename Container::value_type& x : container) {
if (x->*ptr == t)
return x;
}
return typename Container::value_type{};
}
struct Object {
int ID, value;
std::string name;
Object (int i, int v, const std::string& n) : ID(i), value(v), name(n) {}
};
std::list<Object*> objects { new Object(5,6,"Sam"), new Object(11,7,"Mark"), new Object(9,12,"Rob"),
new Object(2,11,"Tom"), new Object(15,16,"John") };
int main() {
const Object* object = searchByDataMember (objects, 11, &Object::value);
std::cout << object->name << '\n'; // Tom
}
Suppose you have a structure. Inside of that structure are
* some sort of name
* two variables of the same type but with different meaning
struct foo {
std::string a;
std::string b;
};
Okay, now let's say you have a bunch of foos in a container:
// key: some sort of name, value: a foo instance
std::map<std::string, foo> container;
Okay, now suppose you load the data from separate sources, but the data is presented in the same fashion (eg, you need the same parsing method).
You could do something like this:
void readDataFromText(std::istream & input, std::map<std::string, foo> & container, std::string foo::*storage) {
std::string line, name, value;
// while lines are successfully retrieved
while (std::getline(input, line)) {
std::stringstream linestr(line);
if ( line.empty() ) {
continue;
}
// retrieve name and value
linestr >> name >> value;
// store value into correct storage, whichever one is correct
container[name].*storage = value;
}
}
std::map<std::string, foo> readValues() {
std::map<std::string, foo> foos;
std::ifstream a("input-a");
readDataFromText(a, foos, &foo::a);
std::ifstream b("input-b");
readDataFromText(b, foos, &foo::b);
return foos;
}
At this point, calling readValues() will return a container with a unison of "input-a" and "input-b"; all keys will be present, and foos with have either a or b or both.
Just to add some use cases for #anon's & #Oktalist's answer, here's a great reading material about pointer-to-member-function and pointer-to-member-data.
https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-ptmf4.pdf
with pointer to member, we can write generic code like this
template<typename T, typename U>
struct alpha{
T U::*p_some_member;
};
struct beta{
int foo;
};
int main()
{
beta b{};
alpha<int, beta> a{&beta::foo};
b.*(a.p_some_member) = 4;
return 0;
}
I love the * and & operators:
struct X
{
int a {0};
int *ptr {NULL};
int &fa() { return a; }
int *&fptr() { return ptr; }
};
int main(void)
{
X x;
int X::*p1 = &X::a; // pointer-to-member 'int X::a'. Type of p1 = 'int X::*'
x.*p1 = 10;
int *X::*p2 = &X::ptr; // pointer-to-member-pointer 'int *X::ptr'. Type of p2 = 'int *X::*'
x.*p2 = nullptr;
X *xx;
xx->*p2 = nullptr;
int& (X::*p3)() = X::fa; // pointer-to-member-function 'X::fa'. Type of p3 = 'int &(X::*)()'
(x.*p3)() = 20;
(xx->*p3)() = 30;
int *&(X::*p4)() = X::fptr; // pointer-to-member-function 'X::fptr'. Type of p4 = 'int *&(X::*)()'
(x.*p4)() = nullptr;
(xx->*p4)() = nullptr;
}
Indeed all is true as long as the members are public, or static
I think you'd only want to do this if the member data was pretty large (e.g., an object of another pretty hefty class), and you have some external routine which only works on references to objects of that class. You don't want to copy the member object, so this lets you pass it around.
A realworld example of a pointer-to-member could be a more narrow aliasing constructor for std::shared_ptr:
template <typename T>
template <typename U>
shared_ptr<T>::shared_ptr(const shared_ptr<U>, T U::*member);
What that constructor would be good for
assume you have a struct foo:
struct foo {
int ival;
float fval;
};
If you have given a shared_ptr to a foo, you could then retrieve shared_ptr's to its members ival or fval using that constructor:
auto foo_shared = std::make_shared<foo>();
auto ival_shared = std::shared_ptr<int>(foo_shared, &foo::ival);
This would be useful if want to pass the pointer foo_shared->ival to some function which expects a shared_ptr
https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
Pointer to members are C++'s type safe equivalent for C's offsetof(), which is defined in stddef.h: Both return the information, where a certain field is located within a class or struct. While offsetof() may be used with certain simple enough classes also in C++, it fails miserably for the general case, especially with virtual base classes. So pointer to members were added to the standard. They also provide easier syntax to reference an actual field:
struct C { int a; int b; } c;
int C::* intptr = &C::a; // or &C::b, depending on the field wanted
c.*intptr += 1;
is much easier than:
struct C { int a; int b; } c;
int intoffset = offsetof(struct C, a);
* (int *) (((char *) (void *) &c) + intoffset) += 1;
As to why one wants to use offsetof() (or pointer to members), there are good answers elsewhere on stackoverflow. One example is here: How does the C offsetof macro work?

What does Obj::* mean? [duplicate]

I came across this strange code snippet which compiles fine:
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
return 0;
}
Why does C++ have this pointer to a non-static data member of a class? What is the use of this strange pointer in real code?
It's a "pointer to member" - the following code illustrates its use:
#include <iostream>
using namespace std;
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
Car c1;
c1.speed = 1; // direct access
cout << "speed is " << c1.speed << endl;
c1.*pSpeed = 2; // access via pointer to member
cout << "speed is " << c1.speed << endl;
return 0;
}
As to why you would want to do that, well it gives you another level of indirection that can solve some tricky problems. But to be honest, I've never had to use them in my own code.
Edit: I can't think off-hand of a convincing use for pointers to member data. Pointer to member functions can be used in pluggable architectures, but once again producing an example in a small space defeats me. The following is my best (untested) try - an Apply function that would do some pre &post processing before applying a user-selected member function to an object:
void Apply( SomeClass * c, void (SomeClass::*func)() ) {
// do hefty pre-call processing
(c->*func)(); // call user specified function
// do hefty post-call processing
}
The parentheses around c->*func are necessary because the ->* operator has lower precedence than the function call operator.
This is the simplest example I can think of that conveys the rare cases where this feature is pertinent:
#include <iostream>
class bowl {
public:
int apples;
int oranges;
};
int count_fruit(bowl * begin, bowl * end, int bowl::*fruit)
{
int count = 0;
for (bowl * iterator = begin; iterator != end; ++ iterator)
count += iterator->*fruit;
return count;
}
int main()
{
bowl bowls[2] = {
{ 1, 2 },
{ 3, 5 }
};
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::apples) << " apples\n";
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::oranges) << " oranges\n";
return 0;
}
The thing to note here is the pointer passed in to count_fruit. This saves you having to write separate count_apples and count_oranges functions.
Another application are intrusive lists. The element type can tell the list what its next/prev pointers are. So the list does not use hard-coded names but can still use existing pointers:
// say this is some existing structure. And we want to use
// a list. We can tell it that the next pointer
// is apple::next.
struct apple {
int data;
apple * next;
};
// simple example of a minimal intrusive list. Could specify the
// member pointer as template argument too, if we wanted:
// template<typename E, E *E::*next_ptr>
template<typename E>
struct List {
List(E *E::*next_ptr):head(0), next_ptr(next_ptr) { }
void add(E &e) {
// access its next pointer by the member pointer
e.*next_ptr = head;
head = &e;
}
E * head;
E *E::*next_ptr;
};
int main() {
List<apple> lst(&apple::next);
apple a;
lst.add(a);
}
Here's a real-world example I am working on right now, from signal processing / control systems:
Suppose you have some structure that represents the data you are collecting:
struct Sample {
time_t time;
double value1;
double value2;
double value3;
};
Now suppose that you stuff them into a vector:
std::vector<Sample> samples;
... fill the vector ...
Now suppose that you want to calculate some function (say the mean) of one of the variables over a range of samples, and you want to factor this mean calculation into a function. The pointer-to-member makes it easy:
double Mean(std::vector<Sample>::const_iterator begin,
std::vector<Sample>::const_iterator end,
double Sample::* var)
{
float mean = 0;
int samples = 0;
for(; begin != end; begin++) {
const Sample& s = *begin;
mean += s.*var;
samples++;
}
mean /= samples;
return mean;
}
...
double mean = Mean(samples.begin(), samples.end(), &Sample::value2);
Note Edited 2016/08/05 for a more concise template-function approach
And, of course, you can template it to compute a mean for any forward-iterator and any value type that supports addition with itself and division by size_t:
template<typename Titer, typename S>
S mean(Titer begin, const Titer& end, S std::iterator_traits<Titer>::value_type::* var) {
using T = typename std::iterator_traits<Titer>::value_type;
S sum = 0;
size_t samples = 0;
for( ; begin != end ; ++begin ) {
const T& s = *begin;
sum += s.*var;
samples++;
}
return sum / samples;
}
struct Sample {
double x;
}
std::vector<Sample> samples { {1.0}, {2.0}, {3.0} };
double m = mean(samples.begin(), samples.end(), &Sample::x);
EDIT - The above code has performance implications
You should note, as I soon discovered, that the code above has some serious performance implications. The summary is that if you're calculating a summary statistic on a time series, or calculating an FFT etc, then you should store the values for each variable contiguously in memory. Otherwise, iterating over the series will cause a cache miss for every value retrieved.
Consider the performance of this code:
struct Sample {
float w, x, y, z;
};
std::vector<Sample> series = ...;
float sum = 0;
int samples = 0;
for(auto it = series.begin(); it != series.end(); it++) {
sum += *it.x;
samples++;
}
float mean = sum / samples;
On many architectures, one instance of Sample will fill a cache line. So on each iteration of the loop, one sample will be pulled from memory into the cache. 4 bytes from the cache line will be used and the rest thrown away, and the next iteration will result in another cache miss, memory access and so on.
Much better to do this:
struct Samples {
std::vector<float> w, x, y, z;
};
Samples series = ...;
float sum = 0;
float samples = 0;
for(auto it = series.x.begin(); it != series.x.end(); it++) {
sum += *it;
samples++;
}
float mean = sum / samples;
Now when the first x value is loaded from memory, the next three will also be loaded into the cache (supposing suitable alignment), meaning you don't need any values loaded for the next three iterations.
The above algorithm can be improved somewhat further through the use of SIMD instructions on eg SSE2 architectures. However, these work much better if the values are all contiguous in memory and you can use a single instruction to load four samples together (more in later SSE versions).
YMMV - design your data structures to suit your algorithm.
You can later access this member, on any instance:
int main()
{
int Car::*pSpeed = &Car::speed;
Car myCar;
Car yourCar;
int mySpeed = myCar.*pSpeed;
int yourSpeed = yourCar.*pSpeed;
assert(mySpeed > yourSpeed); // ;-)
return 0;
}
Note that you do need an instance to call it on, so it does not work like a delegate.
It is used rarely, I've needed it maybe once or twice in all my years.
Normally using an interface (i.e. a pure base class in C++) is the better design choice.
IBM has some more documentation on how to use this. Briefly, you're using the pointer as an offset into the class. You can't use these pointers apart from the class they refer to, so:
int Car::*pSpeed = &Car::speed;
Car mycar;
mycar.*pSpeed = 65;
It seems a little obscure, but one possible application is if you're trying to write code for deserializing generic data into many different object types, and your code needs to handle object types that it knows absolutely nothing about (for example, your code is in a library, and the objects into which you deserialize were created by a user of your library). The member pointers give you a generic, semi-legible way of referring to the individual data member offsets, without having to resort to typeless void * tricks the way you might for C structs.
It makes it possible to bind member variables and functions in the uniform manner. The following is example with your Car class. More common usage would be binding std::pair::first and ::second when using in STL algorithms and Boost on a map.
#include <list>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
class Car {
public:
Car(int s): speed(s) {}
void drive() {
std::cout << "Driving at " << speed << " km/h" << std::endl;
}
int speed;
};
int main() {
using namespace std;
using namespace boost::lambda;
list<Car> l;
l.push_back(Car(10));
l.push_back(Car(140));
l.push_back(Car(130));
l.push_back(Car(60));
// Speeding cars
list<Car> s;
// Binding a value to a member variable.
// Find all cars with speed over 60 km/h.
remove_copy_if(l.begin(), l.end(),
back_inserter(s),
bind(&Car::speed, _1) <= 60);
// Binding a value to a member function.
// Call a function on each car.
for_each(s.begin(), s.end(), bind(&Car::drive, _1));
return 0;
}
You can use an array of pointer to (homogeneous) member data to enable a dual, named-member (i.e. x.data) and array-subscript (i.e. x[idx]) interface.
#include <cassert>
#include <cstddef>
struct vector3 {
float x;
float y;
float z;
float& operator[](std::size_t idx) {
static float vector3::*component[3] = {
&vector3::x, &vector3::y, &vector3::z
};
return this->*component[idx];
}
};
int main()
{
vector3 v = { 0.0f, 1.0f, 2.0f };
assert(&v[0] == &v.x);
assert(&v[1] == &v.y);
assert(&v[2] == &v.z);
for (std::size_t i = 0; i < 3; ++i) {
v[i] += 1.0f;
}
assert(v.x == 1.0f);
assert(v.y == 2.0f);
assert(v.z == 3.0f);
return 0;
}
One way I've used it is if I have two implementations of how to do something in a class and I want to choose one at run-time without having to continually go through an if statement i.e.
class Algorithm
{
public:
Algorithm() : m_impFn( &Algorithm::implementationA ) {}
void frequentlyCalled()
{
// Avoid if ( using A ) else if ( using B ) type of thing
(this->*m_impFn)();
}
private:
void implementationA() { /*...*/ }
void implementationB() { /*...*/ }
typedef void ( Algorithm::*IMP_FN ) ();
IMP_FN m_impFn;
};
Obviously this is only practically useful if you feel the code is being hammered enough that the if statement is slowing things done eg. deep in the guts of some intensive algorithm somewhere. I still think it's more elegant than the if statement even in situations where it has no practical use but that's just my opnion.
Pointers to classes are not real pointers; a class is a logical construct and has no physical existence in memory, however, when you construct a pointer to a member of a class it gives an offset into an object of the member's class where the member can be found; This gives an important conclusion: Since static members are not associated with any object so a pointer to a member CANNOT point to a static member(data or functions) whatsoever
Consider the following:
class x {
public:
int val;
x(int i) { val = i;}
int get_val() { return val; }
int d_val(int i) {return i+i; }
};
int main() {
int (x::* data) = &x::val; //pointer to data member
int (x::* func)(int) = &x::d_val; //pointer to function member
x ob1(1), ob2(2);
cout <<ob1.*data;
cout <<ob2.*data;
cout <<(ob1.*func)(ob1.*data);
cout <<(ob2.*func)(ob2.*data);
return 0;
}
Source: The Complete Reference C++ - Herbert Schildt 4th Edition
Here is an example where pointer to data members could be useful:
#include <iostream>
#include <list>
#include <string>
template <typename Container, typename T, typename DataPtr>
typename Container::value_type searchByDataMember (const Container& container, const T& t, DataPtr ptr) {
for (const typename Container::value_type& x : container) {
if (x->*ptr == t)
return x;
}
return typename Container::value_type{};
}
struct Object {
int ID, value;
std::string name;
Object (int i, int v, const std::string& n) : ID(i), value(v), name(n) {}
};
std::list<Object*> objects { new Object(5,6,"Sam"), new Object(11,7,"Mark"), new Object(9,12,"Rob"),
new Object(2,11,"Tom"), new Object(15,16,"John") };
int main() {
const Object* object = searchByDataMember (objects, 11, &Object::value);
std::cout << object->name << '\n'; // Tom
}
Suppose you have a structure. Inside of that structure are
* some sort of name
* two variables of the same type but with different meaning
struct foo {
std::string a;
std::string b;
};
Okay, now let's say you have a bunch of foos in a container:
// key: some sort of name, value: a foo instance
std::map<std::string, foo> container;
Okay, now suppose you load the data from separate sources, but the data is presented in the same fashion (eg, you need the same parsing method).
You could do something like this:
void readDataFromText(std::istream & input, std::map<std::string, foo> & container, std::string foo::*storage) {
std::string line, name, value;
// while lines are successfully retrieved
while (std::getline(input, line)) {
std::stringstream linestr(line);
if ( line.empty() ) {
continue;
}
// retrieve name and value
linestr >> name >> value;
// store value into correct storage, whichever one is correct
container[name].*storage = value;
}
}
std::map<std::string, foo> readValues() {
std::map<std::string, foo> foos;
std::ifstream a("input-a");
readDataFromText(a, foos, &foo::a);
std::ifstream b("input-b");
readDataFromText(b, foos, &foo::b);
return foos;
}
At this point, calling readValues() will return a container with a unison of "input-a" and "input-b"; all keys will be present, and foos with have either a or b or both.
Just to add some use cases for #anon's & #Oktalist's answer, here's a great reading material about pointer-to-member-function and pointer-to-member-data.
https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-ptmf4.pdf
with pointer to member, we can write generic code like this
template<typename T, typename U>
struct alpha{
T U::*p_some_member;
};
struct beta{
int foo;
};
int main()
{
beta b{};
alpha<int, beta> a{&beta::foo};
b.*(a.p_some_member) = 4;
return 0;
}
I love the * and & operators:
struct X
{
int a {0};
int *ptr {NULL};
int &fa() { return a; }
int *&fptr() { return ptr; }
};
int main(void)
{
X x;
int X::*p1 = &X::a; // pointer-to-member 'int X::a'. Type of p1 = 'int X::*'
x.*p1 = 10;
int *X::*p2 = &X::ptr; // pointer-to-member-pointer 'int *X::ptr'. Type of p2 = 'int *X::*'
x.*p2 = nullptr;
X *xx;
xx->*p2 = nullptr;
int& (X::*p3)() = X::fa; // pointer-to-member-function 'X::fa'. Type of p3 = 'int &(X::*)()'
(x.*p3)() = 20;
(xx->*p3)() = 30;
int *&(X::*p4)() = X::fptr; // pointer-to-member-function 'X::fptr'. Type of p4 = 'int *&(X::*)()'
(x.*p4)() = nullptr;
(xx->*p4)() = nullptr;
}
Indeed all is true as long as the members are public, or static
I think you'd only want to do this if the member data was pretty large (e.g., an object of another pretty hefty class), and you have some external routine which only works on references to objects of that class. You don't want to copy the member object, so this lets you pass it around.
A realworld example of a pointer-to-member could be a more narrow aliasing constructor for std::shared_ptr:
template <typename T>
template <typename U>
shared_ptr<T>::shared_ptr(const shared_ptr<U>, T U::*member);
What that constructor would be good for
assume you have a struct foo:
struct foo {
int ival;
float fval;
};
If you have given a shared_ptr to a foo, you could then retrieve shared_ptr's to its members ival or fval using that constructor:
auto foo_shared = std::make_shared<foo>();
auto ival_shared = std::shared_ptr<int>(foo_shared, &foo::ival);
This would be useful if want to pass the pointer foo_shared->ival to some function which expects a shared_ptr
https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
Pointer to members are C++'s type safe equivalent for C's offsetof(), which is defined in stddef.h: Both return the information, where a certain field is located within a class or struct. While offsetof() may be used with certain simple enough classes also in C++, it fails miserably for the general case, especially with virtual base classes. So pointer to members were added to the standard. They also provide easier syntax to reference an actual field:
struct C { int a; int b; } c;
int C::* intptr = &C::a; // or &C::b, depending on the field wanted
c.*intptr += 1;
is much easier than:
struct C { int a; int b; } c;
int intoffset = offsetof(struct C, a);
* (int *) (((char *) (void *) &c) + intoffset) += 1;
As to why one wants to use offsetof() (or pointer to members), there are good answers elsewhere on stackoverflow. One example is here: How does the C offsetof macro work?

The most efficient way to assign values to a bunch of variables

Suppose we have some integer variables, and all of them should get their values from a struct called "numberpool" via function call, and the value assignment should only be done by "entrykey":
struct numberpool{
vector<int> numbers(100);
};
void assign(struct numberpool& src, int entrykey, int& dest){ // call by reference
dest = src.numbers[tag];
return ;
}
int main(){
struct numberpool pool;
...... // pool initialization
int a, b, c, d, e .... z; // 26 integers declaration
// Assigning
assign(pool, 1, a);
assign(pool, 5, b);
assign(pool, 23, c);
....and so on.
return 0;
}
I'd like to know, is this the fastest way to complete this job? I doubt that there is more efficient way to do this, due to the frequently function calls.
What if I define another struct containing all the int variables, and just call a function once, would it help ?
The performance of the function calls is not your problem here. The compiler will be able to optimize it quite well.
However, seeing so many variables makes me cringe. Unless you really have a meaning behind each and every of the variables (apart from being letters of the alphabet), you should think about another design. If you really want to map the alphabet to numbers, you should just use an array.
Use method instead of standalone function and assign natural way:
struct numberpool{
vector<int> numbers(100);
int get( size_t tag ) const { return numbers[tag] };
};
int main(){
numberpool pool;
...... // pool initialization
int a = pool.get(1);
int b = pool.get(5);
....and so on.
return 0;
}
If the majority of your "tag" indices are grouped closely together, you can copy the underlying data as a single block:
struct subrange{
static size_t min_ndx() constexpr { return 1; }
static size_t max_ndx() constexpr { return 23; }
static size_t storage_size() constexpr { return max_ndx() - min_ndx() + 1; }
array<int, storage_size()> storage;
int outlier_99; // Avoid copying indices between 24 and 99
// accessors
int &a() { return storage[1 - min_ndx()]; }
int &b() { return storage[5 - min_ndx()]; }
int &c() { return storage[23 - min_ndx()]; }
int &d() { return outlier_99; }
// Constructor allows numberpool to copy its vector
subrange(const vector<int>& numbers)
:storage(numbers.cbegin() + min_ndx(),
numbers.cbegin() + min_ndx() + storage_size()),
outlier_99(numbers[99])
{}
};
struct numberpool{
vector<int> numbers(100);
subrange copy_subrange( ) const {
return subrange(numbers); };
};
main()
{
numberpool pool;
...... // pool initialization
// Copy a subset of memory, including data you're interested in,
// and some chunks in between you're not.
auto extracted = pool.copy_subrange();
int sum = extracted.a() + extracted.b() + extracted.c() + extracted.d();
Copying a block of memory may or may not be faster, depending on your exact situation. When in doubt, try both ways.

What does Class::* do? [duplicate]

I came across this strange code snippet which compiles fine:
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
return 0;
}
Why does C++ have this pointer to a non-static data member of a class? What is the use of this strange pointer in real code?
It's a "pointer to member" - the following code illustrates its use:
#include <iostream>
using namespace std;
class Car
{
public:
int speed;
};
int main()
{
int Car::*pSpeed = &Car::speed;
Car c1;
c1.speed = 1; // direct access
cout << "speed is " << c1.speed << endl;
c1.*pSpeed = 2; // access via pointer to member
cout << "speed is " << c1.speed << endl;
return 0;
}
As to why you would want to do that, well it gives you another level of indirection that can solve some tricky problems. But to be honest, I've never had to use them in my own code.
Edit: I can't think off-hand of a convincing use for pointers to member data. Pointer to member functions can be used in pluggable architectures, but once again producing an example in a small space defeats me. The following is my best (untested) try - an Apply function that would do some pre &post processing before applying a user-selected member function to an object:
void Apply( SomeClass * c, void (SomeClass::*func)() ) {
// do hefty pre-call processing
(c->*func)(); // call user specified function
// do hefty post-call processing
}
The parentheses around c->*func are necessary because the ->* operator has lower precedence than the function call operator.
This is the simplest example I can think of that conveys the rare cases where this feature is pertinent:
#include <iostream>
class bowl {
public:
int apples;
int oranges;
};
int count_fruit(bowl * begin, bowl * end, int bowl::*fruit)
{
int count = 0;
for (bowl * iterator = begin; iterator != end; ++ iterator)
count += iterator->*fruit;
return count;
}
int main()
{
bowl bowls[2] = {
{ 1, 2 },
{ 3, 5 }
};
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::apples) << " apples\n";
std::cout << "I have " << count_fruit(bowls, bowls + 2, & bowl::oranges) << " oranges\n";
return 0;
}
The thing to note here is the pointer passed in to count_fruit. This saves you having to write separate count_apples and count_oranges functions.
Another application are intrusive lists. The element type can tell the list what its next/prev pointers are. So the list does not use hard-coded names but can still use existing pointers:
// say this is some existing structure. And we want to use
// a list. We can tell it that the next pointer
// is apple::next.
struct apple {
int data;
apple * next;
};
// simple example of a minimal intrusive list. Could specify the
// member pointer as template argument too, if we wanted:
// template<typename E, E *E::*next_ptr>
template<typename E>
struct List {
List(E *E::*next_ptr):head(0), next_ptr(next_ptr) { }
void add(E &e) {
// access its next pointer by the member pointer
e.*next_ptr = head;
head = &e;
}
E * head;
E *E::*next_ptr;
};
int main() {
List<apple> lst(&apple::next);
apple a;
lst.add(a);
}
Here's a real-world example I am working on right now, from signal processing / control systems:
Suppose you have some structure that represents the data you are collecting:
struct Sample {
time_t time;
double value1;
double value2;
double value3;
};
Now suppose that you stuff them into a vector:
std::vector<Sample> samples;
... fill the vector ...
Now suppose that you want to calculate some function (say the mean) of one of the variables over a range of samples, and you want to factor this mean calculation into a function. The pointer-to-member makes it easy:
double Mean(std::vector<Sample>::const_iterator begin,
std::vector<Sample>::const_iterator end,
double Sample::* var)
{
float mean = 0;
int samples = 0;
for(; begin != end; begin++) {
const Sample& s = *begin;
mean += s.*var;
samples++;
}
mean /= samples;
return mean;
}
...
double mean = Mean(samples.begin(), samples.end(), &Sample::value2);
Note Edited 2016/08/05 for a more concise template-function approach
And, of course, you can template it to compute a mean for any forward-iterator and any value type that supports addition with itself and division by size_t:
template<typename Titer, typename S>
S mean(Titer begin, const Titer& end, S std::iterator_traits<Titer>::value_type::* var) {
using T = typename std::iterator_traits<Titer>::value_type;
S sum = 0;
size_t samples = 0;
for( ; begin != end ; ++begin ) {
const T& s = *begin;
sum += s.*var;
samples++;
}
return sum / samples;
}
struct Sample {
double x;
}
std::vector<Sample> samples { {1.0}, {2.0}, {3.0} };
double m = mean(samples.begin(), samples.end(), &Sample::x);
EDIT - The above code has performance implications
You should note, as I soon discovered, that the code above has some serious performance implications. The summary is that if you're calculating a summary statistic on a time series, or calculating an FFT etc, then you should store the values for each variable contiguously in memory. Otherwise, iterating over the series will cause a cache miss for every value retrieved.
Consider the performance of this code:
struct Sample {
float w, x, y, z;
};
std::vector<Sample> series = ...;
float sum = 0;
int samples = 0;
for(auto it = series.begin(); it != series.end(); it++) {
sum += *it.x;
samples++;
}
float mean = sum / samples;
On many architectures, one instance of Sample will fill a cache line. So on each iteration of the loop, one sample will be pulled from memory into the cache. 4 bytes from the cache line will be used and the rest thrown away, and the next iteration will result in another cache miss, memory access and so on.
Much better to do this:
struct Samples {
std::vector<float> w, x, y, z;
};
Samples series = ...;
float sum = 0;
float samples = 0;
for(auto it = series.x.begin(); it != series.x.end(); it++) {
sum += *it;
samples++;
}
float mean = sum / samples;
Now when the first x value is loaded from memory, the next three will also be loaded into the cache (supposing suitable alignment), meaning you don't need any values loaded for the next three iterations.
The above algorithm can be improved somewhat further through the use of SIMD instructions on eg SSE2 architectures. However, these work much better if the values are all contiguous in memory and you can use a single instruction to load four samples together (more in later SSE versions).
YMMV - design your data structures to suit your algorithm.
You can later access this member, on any instance:
int main()
{
int Car::*pSpeed = &Car::speed;
Car myCar;
Car yourCar;
int mySpeed = myCar.*pSpeed;
int yourSpeed = yourCar.*pSpeed;
assert(mySpeed > yourSpeed); // ;-)
return 0;
}
Note that you do need an instance to call it on, so it does not work like a delegate.
It is used rarely, I've needed it maybe once or twice in all my years.
Normally using an interface (i.e. a pure base class in C++) is the better design choice.
IBM has some more documentation on how to use this. Briefly, you're using the pointer as an offset into the class. You can't use these pointers apart from the class they refer to, so:
int Car::*pSpeed = &Car::speed;
Car mycar;
mycar.*pSpeed = 65;
It seems a little obscure, but one possible application is if you're trying to write code for deserializing generic data into many different object types, and your code needs to handle object types that it knows absolutely nothing about (for example, your code is in a library, and the objects into which you deserialize were created by a user of your library). The member pointers give you a generic, semi-legible way of referring to the individual data member offsets, without having to resort to typeless void * tricks the way you might for C structs.
It makes it possible to bind member variables and functions in the uniform manner. The following is example with your Car class. More common usage would be binding std::pair::first and ::second when using in STL algorithms and Boost on a map.
#include <list>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
class Car {
public:
Car(int s): speed(s) {}
void drive() {
std::cout << "Driving at " << speed << " km/h" << std::endl;
}
int speed;
};
int main() {
using namespace std;
using namespace boost::lambda;
list<Car> l;
l.push_back(Car(10));
l.push_back(Car(140));
l.push_back(Car(130));
l.push_back(Car(60));
// Speeding cars
list<Car> s;
// Binding a value to a member variable.
// Find all cars with speed over 60 km/h.
remove_copy_if(l.begin(), l.end(),
back_inserter(s),
bind(&Car::speed, _1) <= 60);
// Binding a value to a member function.
// Call a function on each car.
for_each(s.begin(), s.end(), bind(&Car::drive, _1));
return 0;
}
You can use an array of pointer to (homogeneous) member data to enable a dual, named-member (i.e. x.data) and array-subscript (i.e. x[idx]) interface.
#include <cassert>
#include <cstddef>
struct vector3 {
float x;
float y;
float z;
float& operator[](std::size_t idx) {
static float vector3::*component[3] = {
&vector3::x, &vector3::y, &vector3::z
};
return this->*component[idx];
}
};
int main()
{
vector3 v = { 0.0f, 1.0f, 2.0f };
assert(&v[0] == &v.x);
assert(&v[1] == &v.y);
assert(&v[2] == &v.z);
for (std::size_t i = 0; i < 3; ++i) {
v[i] += 1.0f;
}
assert(v.x == 1.0f);
assert(v.y == 2.0f);
assert(v.z == 3.0f);
return 0;
}
One way I've used it is if I have two implementations of how to do something in a class and I want to choose one at run-time without having to continually go through an if statement i.e.
class Algorithm
{
public:
Algorithm() : m_impFn( &Algorithm::implementationA ) {}
void frequentlyCalled()
{
// Avoid if ( using A ) else if ( using B ) type of thing
(this->*m_impFn)();
}
private:
void implementationA() { /*...*/ }
void implementationB() { /*...*/ }
typedef void ( Algorithm::*IMP_FN ) ();
IMP_FN m_impFn;
};
Obviously this is only practically useful if you feel the code is being hammered enough that the if statement is slowing things done eg. deep in the guts of some intensive algorithm somewhere. I still think it's more elegant than the if statement even in situations where it has no practical use but that's just my opnion.
Pointers to classes are not real pointers; a class is a logical construct and has no physical existence in memory, however, when you construct a pointer to a member of a class it gives an offset into an object of the member's class where the member can be found; This gives an important conclusion: Since static members are not associated with any object so a pointer to a member CANNOT point to a static member(data or functions) whatsoever
Consider the following:
class x {
public:
int val;
x(int i) { val = i;}
int get_val() { return val; }
int d_val(int i) {return i+i; }
};
int main() {
int (x::* data) = &x::val; //pointer to data member
int (x::* func)(int) = &x::d_val; //pointer to function member
x ob1(1), ob2(2);
cout <<ob1.*data;
cout <<ob2.*data;
cout <<(ob1.*func)(ob1.*data);
cout <<(ob2.*func)(ob2.*data);
return 0;
}
Source: The Complete Reference C++ - Herbert Schildt 4th Edition
Here is an example where pointer to data members could be useful:
#include <iostream>
#include <list>
#include <string>
template <typename Container, typename T, typename DataPtr>
typename Container::value_type searchByDataMember (const Container& container, const T& t, DataPtr ptr) {
for (const typename Container::value_type& x : container) {
if (x->*ptr == t)
return x;
}
return typename Container::value_type{};
}
struct Object {
int ID, value;
std::string name;
Object (int i, int v, const std::string& n) : ID(i), value(v), name(n) {}
};
std::list<Object*> objects { new Object(5,6,"Sam"), new Object(11,7,"Mark"), new Object(9,12,"Rob"),
new Object(2,11,"Tom"), new Object(15,16,"John") };
int main() {
const Object* object = searchByDataMember (objects, 11, &Object::value);
std::cout << object->name << '\n'; // Tom
}
Suppose you have a structure. Inside of that structure are
* some sort of name
* two variables of the same type but with different meaning
struct foo {
std::string a;
std::string b;
};
Okay, now let's say you have a bunch of foos in a container:
// key: some sort of name, value: a foo instance
std::map<std::string, foo> container;
Okay, now suppose you load the data from separate sources, but the data is presented in the same fashion (eg, you need the same parsing method).
You could do something like this:
void readDataFromText(std::istream & input, std::map<std::string, foo> & container, std::string foo::*storage) {
std::string line, name, value;
// while lines are successfully retrieved
while (std::getline(input, line)) {
std::stringstream linestr(line);
if ( line.empty() ) {
continue;
}
// retrieve name and value
linestr >> name >> value;
// store value into correct storage, whichever one is correct
container[name].*storage = value;
}
}
std::map<std::string, foo> readValues() {
std::map<std::string, foo> foos;
std::ifstream a("input-a");
readDataFromText(a, foos, &foo::a);
std::ifstream b("input-b");
readDataFromText(b, foos, &foo::b);
return foos;
}
At this point, calling readValues() will return a container with a unison of "input-a" and "input-b"; all keys will be present, and foos with have either a or b or both.
Just to add some use cases for #anon's & #Oktalist's answer, here's a great reading material about pointer-to-member-function and pointer-to-member-data.
https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-ptmf4.pdf
with pointer to member, we can write generic code like this
template<typename T, typename U>
struct alpha{
T U::*p_some_member;
};
struct beta{
int foo;
};
int main()
{
beta b{};
alpha<int, beta> a{&beta::foo};
b.*(a.p_some_member) = 4;
return 0;
}
I love the * and & operators:
struct X
{
int a {0};
int *ptr {NULL};
int &fa() { return a; }
int *&fptr() { return ptr; }
};
int main(void)
{
X x;
int X::*p1 = &X::a; // pointer-to-member 'int X::a'. Type of p1 = 'int X::*'
x.*p1 = 10;
int *X::*p2 = &X::ptr; // pointer-to-member-pointer 'int *X::ptr'. Type of p2 = 'int *X::*'
x.*p2 = nullptr;
X *xx;
xx->*p2 = nullptr;
int& (X::*p3)() = X::fa; // pointer-to-member-function 'X::fa'. Type of p3 = 'int &(X::*)()'
(x.*p3)() = 20;
(xx->*p3)() = 30;
int *&(X::*p4)() = X::fptr; // pointer-to-member-function 'X::fptr'. Type of p4 = 'int *&(X::*)()'
(x.*p4)() = nullptr;
(xx->*p4)() = nullptr;
}
Indeed all is true as long as the members are public, or static
I think you'd only want to do this if the member data was pretty large (e.g., an object of another pretty hefty class), and you have some external routine which only works on references to objects of that class. You don't want to copy the member object, so this lets you pass it around.
A realworld example of a pointer-to-member could be a more narrow aliasing constructor for std::shared_ptr:
template <typename T>
template <typename U>
shared_ptr<T>::shared_ptr(const shared_ptr<U>, T U::*member);
What that constructor would be good for
assume you have a struct foo:
struct foo {
int ival;
float fval;
};
If you have given a shared_ptr to a foo, you could then retrieve shared_ptr's to its members ival or fval using that constructor:
auto foo_shared = std::make_shared<foo>();
auto ival_shared = std::shared_ptr<int>(foo_shared, &foo::ival);
This would be useful if want to pass the pointer foo_shared->ival to some function which expects a shared_ptr
https://en.cppreference.com/w/cpp/memory/shared_ptr/shared_ptr
Pointer to members are C++'s type safe equivalent for C's offsetof(), which is defined in stddef.h: Both return the information, where a certain field is located within a class or struct. While offsetof() may be used with certain simple enough classes also in C++, it fails miserably for the general case, especially with virtual base classes. So pointer to members were added to the standard. They also provide easier syntax to reference an actual field:
struct C { int a; int b; } c;
int C::* intptr = &C::a; // or &C::b, depending on the field wanted
c.*intptr += 1;
is much easier than:
struct C { int a; int b; } c;
int intoffset = offsetof(struct C, a);
* (int *) (((char *) (void *) &c) + intoffset) += 1;
As to why one wants to use offsetof() (or pointer to members), there are good answers elsewhere on stackoverflow. One example is here: How does the C offsetof macro work?

How do I create an object with a default value if none is passed in the parameter?

I'm trying to create a table that will default to size 500 if no value is passed to the constructor.
Example
Table object; //sets table size to 500 by default
Table object(10000); //sets table size to 10000
This is how I currently have my header set up:
Class Table{
public:
Table();
//other functions excluded
private:
static const int tableSize = 500;
std::vector<int> A[tableSize];
};
How can I do this?
This is likely what you're looking for, assuming you wanted a table and not just a sequence. You code made no mention of the size of each row in that table, so I'm going with what you had:
class Table
{
public:
Table(size_t n = tableSize) : A(n) {};
//other functions excluded
private:
static const size_t tableSize = 500;
std::vector< std::vector<int> > A;
};
If that size of your row buffers is fixed (say 100 columns), you could use a std::array<> for your row buffers, and thus this instead:
class Table
{
public:
Table(size_t n = tableSize) : A(n) {};
//other functions excluded
private:
static const size_t tableSize = 500;
std::vector< std::array<int,100> > A;
};
EDIT: Growing Your Hash Table
it appears from comment this is to provide a hash table implementation, and in so doing the need to expand the hash table is required (probably one reason for this in the first place). In that, you can expand the original directly by doing this in conjunction with the first snippet:
void Table::expand()
{
size_t new_size = 2*A.size() + 1;
std::vector< std::vector<int>> tmp(new_size);
for (auto& x : A)
{
std::hash<int> hfn;
for (auto y : x)
tmp[hfn(y) % new_size].push_back(y);
}
std::swap(A,tmp);
}
or something similar. Your hash function would obviously need proper integration as well as potentially taking an optional size factor, etc, but you can hopefully get the idea.
You can do it like so:
Class Table{
public:
Table(int size = 500): A(size) { }
private:
std::vector<int> A;
};
(note that it's shown this way for brevity. You could/should separate the interface from its implementation and define Table::Table in a source file, and the initializer list should go with it.)