Is there any way to iterate through a struct? - c++

I would like to iterate through a struct which is defined in other library whose source is not under my control. So any lib which requires to define the struct with its own macros/adaptors like previous questions is not usable here. I found the closest way is using boost::hana. However, it still requires to fill up an adaptor before I can iterate through it. I attached an example here. I wonder is there any way I can automate the BOOST_HANA_ADAPT_STRUCT then I do not need to fill up all the struct member names in there (those structs in total have more than hundred members).
#include <iostream>
#include <boost/hana.hpp>
#include <typeinfo>
namespace hana=boost::hana;
struct adapt_test
{
std::string name;
int data;
};
BOOST_HANA_ADAPT_STRUCT(
adapt_test
, name
, data
);
auto names = hana::transform(hana::accessors<adapt_test>(), hana::first);
int main() {
hana::for_each(
names,
[] (auto item)
{
std::cout << hana::to<char const *>(item) << std::endl;
}
);
adapt_test s1{"a", 2};
hana::for_each(
s1,
[] (auto pair)
{
std::cout << hana::to<char const *>(hana::first(pair)) << "=" << hana::second(pair) << std::endl;
}
);
return 0;
}

You can use Boost Flat Reflection like:
struct adapt_test
{
std::string name;
int data;
};
adapt_test s1{"a", 2};
std::cout << boost::pfr::get<0>(s1) << std::endl;
std::cout << boost::pfr::get<1>(s1) << std::endl;
boost::pfr::flat_for_each_field(s1, [] (const auto& field) { std::cout << field << std::endl; } );
P.S. Respect for #apolukhin for this library.

The basic answer to your question is no.
C++ does not treat identifiers as string literal (it could be indeed useful in some cases), and there is no bridge unfortunately between these kind of strings.
Hopefully, some standard one day will bring this ability, relieving us from having to go through macros or code generation, or maybe doing differently like this: telling "please treat my struct A { int x, y; } as a pair", where the meaning would be to match type of first and second to the members x and y and then building the types so that it works, it would be really useful for tuples as well. A kind of structured template matching.
Currently the best that can be done to my knowledge is to match structs to tuple without the names (as of C++17) because of the above limitation, such as with boost::hana or boost::fusion as you do.

Related

Can Boost.Pfr be used to iterate the fields of a type as member pointers?

I know that Boost.Pfr can be used to iterate the fields of a type, and visit them as a T&, but since T& can't be cast to T A::*, I'm wondering if there's something in the library I missed that can allow visiting fields as member pointers.
#include <boost/pfr.hpp>
struct A {
int number;
string text;
};
int main() {
boost::pfr::for_each_field(A{1,"foo"},
[](auto A::* field) { // wish this or something similar were possible
}
);
}
PFR doesn't have this (yet?) but if you have recent enough Boost, Describe could be what you're after.
Note it isn't as auto-magic as with PFR, but it does give you the member-pointer information to work with at compile time.
In their "Universal Print Example" you can see that the member descriptor object contains a member pointer which is of pointer-to-member type:
using Md = describe_members<T, mod_any_access>; // for exposition
boost::mp11::mp_for_each<Md>([&](auto D){
if( !first ) { os << ", "; } first = false;
os << "." << D.name << " = " << t.*D.pointer;
});

Creating a class member that is automatically calculated from other class members?

I'm an absolute newbee when it comes to programming and I'm trying to teach myself the basics by just solving some easy "problems" in C++.
I have searched the web for an exact answer to my question before posting it here and haven't found one so far, however that may be because of (1).
So, what I'm looking for is a way to declare a class member that gets automatically calculated from other members of the same class, so that the calculated class member can be used just like an explicitly defined class member would. For example imagine a struct called creature that has the properties/members creature.numberofhands, creature.fingersperhand and finally the property creature.totalfingers that automatically gets calculated from the above members.
Heres an example of the closest I got to what I wanted to achieve:
#include <iostream>
typedef struct creature {
int numberofhands;
int fingersperhand;
int totalfingers();
} creature;
int creature::totalfingers()
{
return numberofhands * fingersperhand;
};
int main()
{
creature human;
human.numberofhands = 2;
human.fingersperhand = 5;
printf("%d",human.totalfingers());
return(0);
}
What's really annoying me about this, is that I have to treat the calculated one DIFFERENTLY from the explicitly defined ones, i.e. I have to put "()" after it.
How can I change the code, so I can use: human.totalfingers without ever explicitly defining it?
The simplest option would be to use public member functions and make the actual properties hidden.
Something like this:
class Creature {
public:
Creature(int numhands, int fingersperhand) // constructor
: m_numhands{numhands}, m_fingersperhand{fingersperhand}
{ }
int fingersPerHand() const { return m_fingersperhand; }
int numberOfHands() const { return m_numhands; }
int totalFingers() const { return numberOfHands() * fingersPerHand(); }
private:
const int m_numhands;
const int m_fingersperhand;
};
The private member variables are an implementation detail. Users of the class just use the three public member functions to get the different number of fingers after construction and don't need to care that two of them are returning constant stored numbers and the third returns a calculated value - that's irrelevant to users.
An example of use:
#include <iostream>
int main()
{
Creature human{2, 5};
std::cout << "A human has "
<< human.totalFingers() << " fingers. "
<< human.fingersPerHand() << " on each of their "
<< human.numberOfHands() << " hands.\n";
return 0;
}
If - as per your comment - you don't want to use a constructor (although that's the safest way to ensure you don't forget to initialize a member), you can modify the class like this:
class CreatureV2 {
public:
int fingersPerHand() const { return m_fingersperhand; }
int numberOfHands() const { return m_numhands; }
int totalFingers() const { return numberOfHands() * fingersPerHand(); }
void setFingersPerHand(int num) { m_fingersperhand = num; }
void setNumberOfHands(int num) { m_numhands = num; }
private:
// Note: these are no longer `const` and I've given them default
// values matching a human, so if you do nothing you'll get
// human hands.
int m_numhands = 2;
int m_fingersperhand = 5;
};
Example of use of the modified class:
#include <iostream>
int main()
{
CreatureV2 human;
std::cout << "A human has "
<< human.totalFingers() << " fingers. "
<< human.fingersPerHand() << " on each of their "
<< human.numberOfHands() << " hands.\n";
CreatureV2 monster;
monster.setFingersPerHand(7);
monster.setNumberOfHands(5);
std::cout << "A monster has "
<< monster.totalFingers() << " fingers. "
<< monster.fingersPerHand() << " on each of their "
<< monster.numberOfHands() << " hands.\n";
CreatureV2 freak;
freak.setFingersPerHand(9);
// Note: I forgot to specify the number of hands, so a freak get
// the default 2.
std::cout << "A freak has "
<< freak.totalFingers() << " fingers. "
<< freak.fingersPerHand() << " on each of their "
<< freak.numberOfHands() << " hands.\n";
return 0;
}
Note: all of the above assumes you are using a modern C++14 compiler.
What you have described is one of the reasons why encapsulation and "member variables should be private" is the recommended way of doing things in C++.
If every variable is accessed through a function, then everything is consistent, and refactoring from a member variable to a computation is possible.
Some languages, like C# or D, have the concept of "properties", which provide a way around the issue, but C++ does not have such a construct.
For fun, the proxy way to avoid extra parenthesis, (but with some extra costs):
class RefMul
{
public:
RefMul(int& a, int& b) : a(a), b(b) {}
operator int() const { return a * b; }
private:
int& a;
int& b;
};
struct creature {
int numberofhands;
int fingersperhand;
RefMul totalfingers{numberofhands, fingersperhand};
};
Demo
Note: to use RefMul with printf, you have to cast to int:
printf("%d", int(human.totalfingers));
That cast would not be required if you use c++ way to print:
std::cout << human.totalfingers;
If you're after consistency, you can make your changes the other way around. Replace the two member variables with constant methods which simply return copies of the member variables. That way, the way you access data is consistent and you don't have to worry about some code changing the values of the member variables when it shouldn't.
Others have provided very good answers. If you are looking for consistency, probably the easiest way is to make use of member functions (as #Jesper Juhl has answered).
On the other hand, if you strictly want to use class members that are calculated automatically from other members, you can use properties. Properties (as are defined in C# and Groovy) are not a standard feature of C++ but there are ways to implement them in C++. This SO question has a very good overview of the ways that properties can be defined and used in C++. My favorite way of defining properties is taking advantage of Microsoft-specific extension for properties in Visual C++ (obviously, this approach is specific to Microsoft Visual C++). A documentation of properties in Visual C++ can be found in MSDN. Using properties in Visual C++, your code can be modified to:
struct creature {
int numberofhands; // use of public member variables are generally discouraged
int fingersperhand;
__declspec(property(get = get_totalfingers)) // Microsoft-specific
int totalfingers;
private:
int fingers;
int get_totalfingers()
{
return numberofhands * fingersperhand; // This is where the automatic calculation takes place.
}
};
This class can be used like this:
#include <iostream>
int main()
{
creature martian;
martian.numberofhands = 2;
martian.fingersperhand = 4; // Marvin the Martian had 4!
// This line will print 8
std::cout << "Total fingers: " << martian.totalfingers << std::endl;
return 0;
}
As I said earlier, properties are not a standard feature of C++ but there are ways to get them in C++ which either rely on smart tricks or using compiler-specific features. IMHO, using simple functions (as #Jesper Juhl described) is a better alternative.

C++ - How to Make Static Dictionary to Lookup Matrix

I am trying to write a C++ class that allows me to access certain matrix elements by a string lookup. I wanted to create a 'static' class that can do this, such as:
#include <unordered_map>
namespace Mine {
static double AA[3][4] = {
{5.04964676394959,-0.693207030363152,0.0422140829479668,-0.000968959310672217},
{2.6044054979329,0.288475262243944,-0.0208805589126506,0.000380899394040856},
{-4.32707864788065,1.07090008760872,-0.0777874445746693,0.00165150952598117}
};
static unordered_map<std::string, double[3][4]> Mine::parameter_store = { {"AA", AA}};
With the idea being that I would have several matrices, and could look them up based on a key. However, this seems to totally and utterly fail with the following error:
error: object expression of non-scalar type 'double [3][4]' cannot be used in a pseudo-destructor expression
Is it possible to build a lookup table this way in C++?
#include <unordered_map>
#include <vector>
namespace Mine{
template<class T>
using Matrix = std::vector<std::vector<T>>;
Matrix<double> AA = {
{5.04964676394959,-0.693207030363152,0.0422140829479668,-0.000968959310672217},
{2.6044054979329,0.288475262243944,-0.0208805589126506,0.000380899394040856},
{-4.32707864788065,1.07090008760872,-0.0777874445746693,0.00165150952598117}
};
static std::unordered_map<std::string, Matrix<double>* > parameter_store = { {"AA", &AA}};
}
#include <iostream>
int main()
{
std::cout << (*Mine::parameter_store["AA"])[0][0] << std::endl;
std::cout << (*Mine::parameter_store["AA"])[0][1] << std::endl;
std::cout << (*Mine::parameter_store["AA"])[1][2] << std::endl;
}
output
5.04965
-0.693207
-0.0208806
The Matrix<> template used here causes each row to store its length even though that's redundant. You can avoid this by used a std::array (but then you're locked into each matrix having equal dimensions since that's part of the type information) or using some library like Boost that provides a multidimensional array. That's an extremely small inefficiency though and unless you know you need to it might be best to not worry about that.
You can try wrapping double[3][4] in a structure/class
structure myMatrix {
double arr[3][4];
//if you want to initialize it
myMatrix(double[3][4] p){
//copy matrix here
}
};

C++ Assigning Values to POD Objects [duplicate]

This question already has answers here:
Correct way of initializing a struct in a class constructor
(5 answers)
Closed 8 years ago.
So I read about Plain Old Data classes (POD) , and decided to make my structs POD to hold data. For example, I have
struct MyClass {
int ID;
int age;
double height;
char[8] Name;
};
Obviously, to assign values to the struct, I can do this:
MyClass.ID = 1;
MyClass.age = 20;
...
But is there anyway to assign raw data, WITHOUT knowing the name of each field?
For example, My program retrieves field value for each column,, and I want to assign the value to the struct, given that i don't know the name of the fields..
MyClass c;
while (MoreColumns()) {
doSomething( c , GetNextColumn() ); //GetNextColumn() returns some value of POD types
}
I'm assuming there's way to do this using memcpy, or something std::copy,, but Not sure how to start..
Sorry if the question is a bit unclear.
You can use aggregate initialization:
MyClass c1 = { 1, 20, 6.0, "Bob" };
MyClass c2;
c2 = MyClass{ 2, 22, 5.5, "Alice" };
There is no general way to loop over the members of a struct or class. There are some tricks to add data and functions to emulate that sort of thing, but they all require additional setup work beyond just declaring the type.
Since MyClass is an aggregate, you can use a brace-initializer to initialize all fields in one call, without naming any of them:
MyClass m {
1,
2,
42.0,
{ "Joseph" }
};
However, given your description, maybe a POD is not a good idea, and you might want to design a class with accessors to set internal fields based on (for example) index columns.
Maybe boost::fusion can help you with what you want to archive.
You can use the adapt macro to iterate over a struct.
From the example of boost:
struct MyClass
{
int ID;
int age;
double height;
};
BOOST_FUSION_ADAPT_STRUCT(
MyClass,
(int, ID)
(int, age)
(double, height)
)
void fillData(int& i)
{
i = 0;
}
void fillData(double& d)
{
d = 99;
}
struct MoreColumns
{
template<typename T>
void operator()(T& t) const
{
fillData(t);
}
};
int main()
{
struct MyClass m = { 33, 5, 2.0 };
std::cout << m.ID << std::endl;
std::cout << m.age << std::endl;
std::cout << m.height << std::endl;
MoreColumns c;
boost::fusion::for_each(m, c);
std::cout << m.ID << std::endl;
std::cout << m.age << std::endl;
std::cout << m.height << std::endl;
}
What you are trying to achieve usually leads to hard-to-read or even unreadable code. However, assuming that you have a genuinely good reason to try to assign (as opposed to initialize) raw data to a field without knowing its name, you could use reinterpret_cast as below (Link here). I don't recommend it, but just want to point out that you have the option.
#include <cstdio>
#include <cstring>
struct Target { // This is your "target"
char foo[8];
};
struct Trap {
// The "trap" which lets you manipulate your target
// without addressing its internals directly.
// Assuming here that an unsigned occupies 4 bytes (not always holds)
unsigned i1, i2;
};
int main() {
Target t;
strcpy(t.foo, "AAAAAAA");
// Ask the compiler to "reinterpet" Target* as Trap*
Trap* tr = reinterpret_cast<Trap*>(&t);
fprintf(stdout, "Before: %s\n", t.foo);
printf("%x %x\n", tr->i1, tr->i2);
// Now manipulate as you please
// Note the byte ordering issue in i2.
// on another architecture, you might have to use 0x42424200
tr->i1 = 0x42424242;
tr->i2 = 0x00424242;
printf("After: %s\n", t.foo);
return 0;
}
This is just a quick example I came up with, you can figure out how to make it "neater". Note that in the above, you could also access target iteratively, by using an array in "Trap" instead of i1, i2 as I have done above.
Let me reiterate, I don't recommend this style, but if you absolutely must do it, this is an option you could explore.

Simple hashmap implementation in C++

I'm relatively new to C++. In Java, it's easy for me to instantiate and use a hashmap. I'd like to know how to do it in a simple way in C++, since I saw many different implementations and none of them looked simple to me.
Most compilers should define std::hash_map for you; in the coming C++0x standard, it will be part of the standard library as std::unordered_map. The STL Page on it is fairly standard. If you use Visual Studio, Microsoft has a page on it.
If you want to use your class as the value, not as the key, then you don't need to do anything special. All primitive types (things like int, char, bool and even char *) should "just work" as keys in a hash_map. However, for anything else you will have to define your own hashing and equality functions and then write "functors" that wrap them in a class.
Assuming your class is called MyClass and you have already defined:
size_t MyClass::HashValue() const { /* something */ }
bool MyClass::Equals(const MyClass& other) const { /* something */ }
You will need to define two functors to wrap those methods in objects.
struct MyClassHash {
size_t operator()(const MyClass& p) const {
return p.HashValue();
}
};
struct MyClassEqual {
bool operator()(const MyClass& c1, const MyClass& c2) const {
return c1.Equals(c2);
}
};
And instantiate your hash_map/hash_set as:
hash_map<MyClass, DataType, MyClassHash, MyClassEqual> my_hash_map;
hash_set<MyClass, MyClassHash, MyClassEqual> my_hash_set;
Everything should work as expected after that.
Using hashmaps in C++ is easy! It's like using standard C++ map. You can use your's compiler/library implementation of unordered_map or use the one provided by boost, or some other vendor. Here's a quick sample. You will find more if you follow the links you were given.
#include <unordered_map>
#include <string>
#include <iostream>
int main()
{
typedef std::tr1::unordered_map< std::string, int > hashmap;
hashmap numbers;
numbers["one"] = 1;
numbers["two"] = 2;
numbers["three"] = 3;
std::tr1::hash< std::string > hashfunc = numbers.hash_function();
for( hashmap::const_iterator i = numbers.begin(), e = numbers.end() ; i != e ; ++i ) {
std::cout << i->first << " -> " << i->second << " (hash = " << hashfunc( i->first ) << ")" << std::endl;
}
return 0;
}
Take a look at boost.unordered, and its data structure.
Try boost's unordered classes.
Check out Simple Hash Map (Hash Table) Implementation in C++ for a basic Hash Table with generic type key-value pairs and separate chaining strategy.