Good day,
I would like to reference a structure in a function by using a variable to store its name. Is this possible to do something like this in C++?
Definitely, all existing structures will be declared and initialised before any call is made (probably as global) and I will build in a check to make sure that only existing structures are referenced.
I would like something in this spirit:
struct StructName
{
...stuff
}a,b,c;
StructName a;
StructName b;
.
.
.
etc. including setting required values (in initialisation or elsewhere in code as needed)
and then I would have something like this to call from another portion of code:
void myFunction(char someInput)
{
some stuff
some stuff
externalFunction(static parameter, static parameter, _someInput_, static parameter);
yet some other stuff
}
where somInput is either a,b or c.
Please bear in mind I am a beginner with C, with little to no formal training in subject matter.
Thank you.
edit: If it was just myself, I would make do with case switch for someInput, referencing the structure directly in each case, but this part of a code is meant to be extendable by a non-programmer who would supply structures themselves, I would provide to him a template of structure initialisation code, and he would add the initialisation code to a specified place in the code, ammend the list of allowed names and compile the library.
You cannot convert a char or a char const * (runtime data) into a type (compile time information).
[edit] Well, actually you can with something like the following code, but since it uses templates, it will still be available only at the compile time, so you will not be able to pass function parameters, for example.
template < char C >
struct GetType;
template < >
struct GetType< 'a' > {
typedef struct { int foo; } type; };
template < >
struct GetType< 'b' > {
typedef struct { int bar; } type; };
GetType< 'a' >::type foo;
GetType< 'b' >::type bar;
Variable names disappear as part of the compilation step(s) in C and C++.
Typically, there are two scenarios that solve the type of problem you are describing:
User input corresponds to specific variable name.
You don't actually want the "name" of the variable, but just need a way to associate different data with different parts of your code.
In the second, simpler case, just use an array, and use the index to the element you want as the way to associate the correct data.
In the first case, you can use a std::map<std::string, structname&>. A std::map acts sort of like an array, but it is indexed by the first type give in the template parameters to std::map - so in this case, you can use std::string as an index.
Something like this:
#include <map>
#include <iostream>
#include <string>
struct StructName
{
int x;
};
std::map<std::string, StructName *> vars;
StructName a;
StructName b;
void registerVars()
{
vars["a"] = &a;
vars["b"] = &b;
}
int main()
{
std::string v;
registerVars();
while(std::cin >> v)
{
std::cin.ignore(1000, '\n');
if (vars.find(v) == vars.end())
{
std::cout << "No such variable" << std::endl;
}
else
{
vars[v]->x++;
std::cout << "variable " << v << " is " << vars[v]->x << std::endl;
}
}
return 0;
}
Related
As the topic suggests, I am trying to create a vector of which can hold any datatype. I am trying to use templates so that code can be more maintainable for future.
#include<iostream>
#include<memory>
#include<vector>
struct prime{
public:
template<typename T>
T get();
};
template<typename T>
struct foo: prime{
public:
T i;
foo(T k):i(k){
}
template<typename T1>
T1 get(){
return i;
}
};
/*
struct fooString :prime{
public:
std::string i;
fooString(std::string k):i(k){
}
};
*/
int main(){
std::vector<std::shared_ptr<prime>> v;
std::shared_ptr<foo<int>> p1 = std::make_shared<foo<int>>(0);
std::shared_ptr<foo<char>> p3 = std::make_shared<foo<char>>('H');
//std::shared_ptr<fooString> p2 = std::make_shared<fooString>("HK");
v.push_back(p1);
v.push_back(p3);
//v.push_back(p2);
//std::cout<<v[0]->i<<" "<<v[1]->i<<std::endl;
//std::cout<<static_cast<foo<int>>(*v[0]).get();
std::cout<<v[0]->get<int>();
}
The commented code is my different approaches I am trying to solve this issue. But I am not able to crack this. Any suggestions would help me a lot. I tried following this SO but as I said, creating union of different datatypes is difficult to maintain. And also boost::variant doesn't help either as I have to give all the types it needs to hold before hand. I don't want that restriction. Can Anyone suggest me whether it is possible or I am just trying to achieve the impossible?
I have another algorithm in my mind which is like cast everything to string and store it. But that approach doesn't look proper.
Thank you :)
If what you want is to have a container that can store any type, but not actually give you any information about it - it's up to you to just know which type each element is actually storing, then that's precisely what std::any (based on Boost.Any) is for.
The usage in your case would be:
int main(){
std::vector<std::any> v;
v.push_back(0); // an int
v.push_back('H'); // a char
v.push_back(std::string{"HK"}); // a string
std::cout << std::any_cast<int>(v[0]); // this will throw if v[0] is not an int
std::string* p = std::any_cast<std::string>(&v[1]); // this will return nullptr
// if v[1] is not a string, which
// it is not
}
I want to implement a function that can print out the value of one member variable (for example, 'aa') of struct ('Data') by it's name.
I try to use the macro definition as follows, but failed.
Is there a simple way to implement it?
#include <string>
#include <iostream>
using namespace std;
struct Data
{
int aa;
int bb;
int cc;
Data(): aa(1),bb(2),cc(3) {};
};
#define Param(a,b) a.##b
void Process(Data& data, const string& name)
{
cout << Param(data, name) << endl;
}
void main()
{
Data data;
Process(data, "aa");//I want print the value of Data.aa
Process(data, "bb");//I want print the value of Data.bb
Process(data, "cc");//I want print the value of Data.cc
}
This is not possible in C++.
This kind of usage is generally seen in scripting languages.
In C++ the variable names are constructed at compile time.
Your original code sample makes no sense to me because if you call Param(name) then the compiler has to know what instance of Data it has to use to determine the value of the member variable you want to get the value of (but I'm neither an expert using macros nor do I like them very much).
I tried to solve your problem using the following approach:
struct Data
{
int aa;
};
#define GetMemberValue(d, n) d.##n
int main()
{
Data d;
d.aa = 3;
int i = GetMemberValue(d, aa);
}
At least this approach returns the right result in this case.
Another thing is that you stated that you cannot call the member variables directly i.e. data.aa so you might run into the same issue using the macro. It's just a guess as I don't know the original code you're using.
I want to make a class that will have a single get template method which will receive an std::string to find in a std::map the right variable and return it.
The std::map should store any type of variable, so I used boost::any, so far the std::map looks like that:
std::map<std::string, boost::any> variables_;
for the get function, I tried something like that:
template <typename T>
T get(std::string& parameter)
{
return variables_[parameter];
}
But no lucky, my question is, is that even possible to do? If so, how?
The basic idea is that I dont want to make an specific method to every specific variable in my class, so other classes dont need to know about every get method of it.
Thanks!
ps: For anyone asking why I want this, here is a resume of it, I have a lot of algorithms, that will run in a certain order, and it will use that for the last one already runned algorithm. So, what I want is to make an xml file, that will tell what algorithms will run, in which order and what data it will use from another algorithm.
So, for example, algorithm A have an variable named "threshold", algorithm B need that information, so, normally it will have to ask it from the A using something like A.getThreshold, but as far as I know, I can't call a object function with it name in an string (from the xml file), so my solution would be have only an get function which i pass the variable name I want and that function will return it to me.
An alternative solution would be to "wrap" the boost::any object into another object which can be automatically converted to anything you want. I don't think it's a good practice but it's the best fit according to your question.
class AnyWrapper {
boost::any value;
public:
AnyWrapper(const boost::any& val) : value(val) {}
template<typename T> operator T() {
return boost::any_cast<T>(value);
}
}
And your getter would be something like :
AnyWrapper get(std::string& parameter)
{
return variables_[parameter]; // variables is a std::map<std::string, boost::any>
}
And then you should be able to retrieve your elements like that :
int integerValue = myContainer.get("age");
std::string stringValue = myContainer.get("name");
But again, this is not a clean solution. There is a reason why the boost authors chose to make the any_cast explicit :)
An boost::any value won't implicitly convert to a type T, you have to request that cast manually:
template <typename T>
T get(std::string& parameter)
{
return boost::any_cast<T>(variables_[parameter]);
}
The call will fail with a boost::bad_any_cast exception if the type stored in the any is not exactly T.
You can also return an boost::any. You lose encapsulation of your implementation, but depending on how you use the return value, it may be the better way.
What you want is not possible as you are trying to mix compile time (template) and runtime (map lookup) code.
You either have to make it fully runtime:
struct base_type { virtual ~base_type{} };
struct derived_type: base_type { ... };
std::map<std::string, base_type*> lookup_map;
base_type* get(std::string const& key) { return lookup_map[key]; }
Or fully compile time (boost.fusion example):
#include <boost/fusion/container/map.hpp>
#include <boost/fusion/sequence/intrinsic/at_key.hpp>
#include <boost/fusion/sequence/intrinsic/value_at_key.hpp>
namespace bf=boost::fusion;
struct key_a; // analogues of string keys in compile time world
struct key_b;
struct key_c;
typedef bf::map<
bf::pair<key_a, long>,
bf::pair<key_b, double>,
bf::pair<key_c, char const*>
> rtmap_t;
rtmap_t rtmap;
template <class Key>
void set_value(typename bf::result_of::value_at_key<rtmap_t, Key>::type const& val)
{
bf::at_key<Key>(rtmap) = val;
}
template <class Key>
typename bf::result_of::at_key<rtmap_t, Key>::type get_value()
{
return bf::at_key<Key>(rtmap);
}
#include <iostream>
int main()
{
char const* cval = "hello metaprogramming";
set_value<key_a>(123l);
set_value<key_b>(456.789);
set_value<key_c>(cval);
std::cout << get_value<key_a>() << std::endl;
std::cout << get_value<key_b>() << std::endl;
std::cout << get_value<key_c>() << std::endl;
return 0;
}
Considering the information you provided in your question I would choose runtime variant with dynamic polymorphism.
Suppose in one program, I'm given:
class Foo {
int x;
double y;
char z;
};
class Bar {
Foo f1;
int t;
Foo f2;
};
int main() {
Bar b;
bar.f1.z = 'h';
bar.f2.z = 'w';
... some crap setting value of b;
FILE *f = fopen("dump", "wb"); // c-style file
fwrite(&b, sizeof(Bar), 1, f);
}
Suppose in another program, I have:
int main() {
File *f = fopen("dump", "rb");
std::string Foo = "int x; double y; char z;";
std::string Bar = "Foo f1; int t; Foo f2;";
// now, given this is it possible to read out
// the value of bar.f1.z and bar.f2.z set earlier?
}
What I'm asking is:
given I have the types of a class, can I figure out how C++ lays it out?
You need to research "serialization". There is a library, Boost Serialization, that people have been recommending.
FWIW, I recommend against using fwrite or std::ostream::write on classes, structures and unions. The compiler is allowed to insert padding between members, so there may be garbage written out. Also, pointers don't serialize very well.
To answer your question, in order to determine which structure to load data from, you need some kind of sentinel to indicate the object type. This can be anything from an enum to the name of the object.
Also investigate the Factory design pattern.
I'm not quite sure what you're asking, so I'll take a leap...
If you really need to figure out where the fields are in a struct, use offsetof.
Note the "POD" restriction in the linked page. This is a C macro, included in C++ for compatibility reasons. We are supposed to use member pointers instead these days, though member pointers don't address all the same problems.
"offsetof" basically imagines an instance of your struct at address zero, and then looks at the address of the field you're interested in. This goes horribly wrong if your struct/class uses multiple or virtual inheritance, since finding the field then involves (typically) a check in the virtual table. Since the imaginary instance at address zero doesn't exist, it doesn't have a virtual table pointer, so you probably get some kind of access violation crash.
Some compilers can cope with this, as they have replaced the traditional offsetof macro with an intrinsic that knows the layout of the struct without trying to do the imaginary-instance trickery. Even so, it's best not to rely on this.
For POD structs, though, offsetof is a convenient way to find the offset to a particular field, and a safe one in that it determines the actual offset irrespective of the alignment applied by your platform.
For the sizeof a field, you obviously just use sizeof. That just leaves platform-specific issues - different layout on different platforms etc due to alignment, endianness and so on ;-)
EDIT
Possibly a silly question, but why not fread the data from the file straight into in instance of the struct, doing essentially what you did with the fwrite but in reverse?
You get the same portability issues as above, meaning your code may not be able to read its own files if recompiled using different options, a different compiler or for a different platform. But for a single-platform app this kind of thing works very well.
You can't assume anything about the order of the bytes that represent Bar. If the file goes across system or that program is compiled with different flags then you'll be reading and writing in different orders.
I've seen a way around this, but it may only work for very simple types.
and I quote from a raknet tutorial:
#pragma pack(push, 1)
struct structName
{
unsigned char typeId; // Your type here
// Your data here
};
#pragma pack(pop)
Noticed the #pragma pack(push,1) and #pragma pack(pop) ? These force your compiler (in this case VC++), to pack the structure as byte-aligned. Check your compiler documentation to learn more.
You want serialization.
For the example that you give, it looks like you really need some sort of C parser that would parse the strings with your type declarations. Then you'd be able to interpret the bytes that you read from the file in the correct way.
Structs in C are laid out member to member in order of declaration. The compiler may insert padding between members according to platform-specific alignment needs. The size of the variables is also platform-specific.
If you have control over the class you can use member pointers. You definitely can do this. The question is whether or not you should...
class Metadata
{
public:
virtual int getOffset() = 0;
};
template <typename THost, typename TField>
class TypedMetadata : Metadata
{
private:
TField (THost::*memberPointer_);
TypedMetadata(TField (THost::*memberPointer))
{
memberPointer_ = memberPointer;
}
public:
static Metadata* getInstance(TField (THost::*memberPointer))
{
return new TypedMetadata<THost, TField>(memberPointer);
}
virtual int getOffset()
{
THost* host = 0;
int result = (int)&(host->*memberPointer_);
return result;
}
};
template<typename THost, typename TField>
Metadata* getTypeMetadata(TField (THost::*memberPointer))
{
return TypedMetadata<THost, TField>::getInstance(memberPointer);
}
class Contained
{
char foo[47];
};
class Container
{
private:
int x;
int y;
Contained contained;
char c1;
char* z;
char c2;
public:
static Metadata** getMetadata()
{
Metadata** metadata = new Metadata*[6];
metadata[0] = getTypeMetadata(&Container::x);
metadata[1] = getTypeMetadata(&Container::y);
metadata[2] = getTypeMetadata(&Container::contained);
metadata[3] = getTypeMetadata(&Container::c1);
metadata[4] = getTypeMetadata(&Container::z);
metadata[5] = getTypeMetadata(&Container::c2);
return metadata;
}
};
int main(array<System::String ^> ^args)
{
Metadata** metadata = Container::getMetadata();
std::cout << metadata[0]->getOffset() << std::endl;
std::cout << metadata[1]->getOffset() << std::endl;
std::cout << metadata[2]->getOffset() << std::endl;
std::cout << metadata[3]->getOffset() << std::endl;
std::cout << metadata[4]->getOffset() << std::endl;
std::cout << metadata[5]->getOffset() << std::endl;
return 0;
}
I'm trying create a class which adds functionality to a generic class, without directly interfacing with the wrapped class. A good example of this would be a smart pointer. Specifically, I'd like to create a wrapper which caches all the i/o for one (or any?) method invoked through the wrapper. Ideally, the cache wrapper have the following properties:
it would not require the wrapping class to be changed in any way (i.e. generic)
it would not require the wrapped class to be changed in any way (i.e. generic)
it would not change the interface or syntax for using the object significantly
For example, it would be really nice to use it like this:
CacheWrapper<NumberCruncher> crunchy;
...
// do some long and ugly calculation, caching method input/output
result = crunchy->calculate(input);
...
// no calculation, use cached result
result = crunchy->calculate(input);
although something goofy like this would be ok:
result = crunchy.dispatch (&NumberCruncher::calculate, input);
I feel like this should be possible in C++, although possibly with some syntactic gymnastics somewhere along the line.
Any ideas?
I think I have the answer you are seeking, or, at least, I almost do. It uses the dispatch style you suggested was goofy, but I think it meets the first two criteria you set forth, and more or less meets the third.
The wrapping class does not have to be modified at all.
It doesn't modify the wrapped class at all.
It only changes the syntax by introducing a dispatch function.
The basic idea is to create a template class, whose parameter is the class of the object to be wrapped, with a template dispatch method, whose parameters are the argument and return types of a member function. The dispatch method looks up the passed in member function pointer to see if it has been called before. If so, it retrieves the record of previous method arguments and calculated results to return the previously calculated value for the argument given to dispatch, or to calculate it if it is new.
Since what this wrapping class does is also called memoization, I've elected to call the template Memo because that is shorter to type than CacheWrapper and I'm starting to prefer shorter names in my old age.
#include <algorithm>
#include <map>
#include <utility>
#include <vector>
// An anonymous namespace to hold a search predicate definition. Users of
// Memo don't need to know this implementation detail, so I keep it
// anonymous. I use a predicate to search a vector of pairs instead of a
// simple map because a map requires that operator< be defined for its key
// type, and operator< isn't defined for member function pointers, but
// operator== is.
namespace {
template <typename Type1, typename Type2>
class FirstEq {
FirstType value;
public:
typedef std::pair<Type1, Type2> ArgType;
FirstEq(Type1 t) : value(t) {}
bool operator()(const ArgType& rhs) const {
return value == rhs.first;
}
};
};
template <typename T>
class Memo {
// Typedef for a member function of T. The C++ standard allows casting a
// member function of a class with one signature to a type of another
// member function of the class with a possibly different signature. You
// aren't guaranteed to be able to call the member function after
// casting, but you can use the pointer for comparisons, which is all we
// need to do.
typedef void (T::*TMemFun)(void);
typedef std::vector< std::pair<TMemFun, void*> > FuncRecords;
T memoized;
FuncRecords funcCalls;
public:
Memo(T t) : memoized(t) {}
template <typename ReturnType, typename ArgType>
ReturnType dispatch(ReturnType (T::* memFun)(ArgType), ArgType arg) {
typedef std::map<ArgType, ReturnType> Record;
// Look up memFun in the record of previously invoked member
// functions. If this is the first invocation, create a new record.
typename FuncRecords::iterator recIter =
find_if(funcCalls.begin(),
funcCalls.end(),
FirstEq<TMemFun, void*>(
reinterpret_cast<TMemFun>(memFun)));
if (recIter == funcCalls.end()) {
funcCalls.push_back(
std::make_pair(reinterpret_cast<TMemFun>(memFun),
static_cast<void*>(new Record)));
recIter = --funcCalls.end();
}
// Get the record of previous arguments and return values.
// Find the previously calculated value, or calculate it if
// necessary.
Record* rec = static_cast<Record*>(
recIter->second);
typename Record::iterator callIter = rec->lower_bound(arg);
if (callIter == rec->end() || callIter->first != arg) {
callIter = rec->insert(callIter,
std::make_pair(arg,
(memoized.*memFun)(arg)));
}
return callIter->second;
}
};
Here is a simple test showing its use:
#include <iostream>
#include <sstream>
#include "Memo.h"
using namespace std;
struct C {
int three(int x) {
cout << "Called three(" << x << ")" << endl;
return 3;
}
double square(float x) {
cout << "Called square(" << x << ")" << endl;
return x * x;
}
};
int main(void) {
C c;
Memo<C> m(c);
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
return 0;
}
Which produces the following output on my system (MacOS 10.4.11 using g++ 4.0.1):
Called three(1)
3
Called three(2)
3
3
3
Called square(2.3)
5.29
5.29
NOTES
This only works for methods which take 1 argument and return a result. It doesn't work for methods which take 0 arguments, or 2, or 3, or more arguments. This shouldn't be a big problem, though. You can implement overloaded versions of dispatch which take different numbers of arguments up to some reasonable max. This is what the Boost Tuple library does. They implement tuples of up to 10 elements and assume most programmers don't need more than that.
The possibility of implementing multiple overloads for dispatch is why I used the FirstEq predicate template with the find_if algorithm instead of a simple for loop search. It is a little more code for a single use, but if you are going to do a similar search multiple times, it ends up being less code overall and less chance to get one of the loops subtlely wrong.
It doesn't work for methods returning nothing, i.e. void, but if the method doesn't return anything, then you don't need to cache the result!
It doesn't work for template member functions of the wrapped class because you need to pass an actual member function pointer to dispatch, and an un-instantiated template function doesn't have a pointer (yet). There may be a way around this, but I haven't tried much yet.
I haven't done much testing of this yet, so it may have some subtle (or not-so-subtle) problems.
I don't think a completely seamless solution which satisfies all your requirements with no change in syntax at all is possible in C++. (though I'd love to be proven wrong!) Hopefully this is close enough.
When I researched this answer, I got a lot of help from this very extensive write up on implementing member function delegates in C++. Anyone who wants to learn way more than they realized was possible to know about member function pointers should give that article a good read.
I don't think this can be easily done using just a wrapper as you'll have to intercept the IO calls, so wrapping a class would put the code at the wrong layer. In essence, you want to substitute the IO code underneath the object, but you're trying to do it from the top layer. If you're thinking of the code as an onion, you're trying to modify the outer skin in order to affect something two or three layers in; IMHO that suggests the design might need a rethink.
If the class that you're trying to wrap/modify this way does allow you to pass in the stream (or whatever IO mechanism you use), then substituting that one for a caching one would be the right thing to do; in essence that would be what you'd be trying to achieve with your wrapper as well.
It looks like a simple task, assuming the "NumberCruncher" has a known interface, let's say int operator(int).
Note that you'll need to make it more complicated to support other interfaces. In order to do so, i'm adding another template parameter, an Adaptor. Adaptor should convert some interface to a known interface. Here's simple and dumb implementation with static method, which is one way to do it. Also look what Functor is.
struct Adaptor1 {
static int invoke(Cached1 & c, int input) {
return(c.foo1(input));
}
};
struct Adaptor2 {
static int invoke(Cached2 & c, int input) {
return(c.foo2(input));
}
};
template class CacheWrapper<typename T, typeneame Adaptor>
{
private:
T m_cachedObj;
std::map<int, int> m_cache;
public:
// add c'tor here
int calculate(int input) {
std::map<int, int>::const_iterator it = m_cache.find(input);
if (it != m_cache.end()) {
return(it->second);
}
int res = Adaptor::invoke(m_cachedObj, input);
m_cache[input] = res;
return(res);
}
};
I think what you need is something like a proxy / decorator (design patterns). You can use templates if you don't need the dynamic part of those patterns. The point is that you need to well define the interface that you will need.
I haven't figured out the case for handling object methods, but I think I've got a good fix for regular functions
template <typename input_t, typename output_t>
class CacheWrapper
{
public:
CacheWrapper (boost::function<output_t (input_t)> f)
: _func(f)
{}
output_t operator() (const input_t& in)
{
if (in != input_)
{
input_ = in;
output_ = _func(in);
}
return output_;
}
private:
boost::function<output_t (input_t)> _func;
input_t input_;
output_t output_;
};
Which would be used as follows:
#include <iostream>
#include "CacheWrapper.h"
double squareit(double x)
{
std::cout << "computing" << std::endl;
return x*x;
}
int main (int argc, char** argv)
{
CacheWrapper<double,double> cached_squareit(squareit);
for (int i=0; i<10; i++)
{
std::cout << cached_squareit (10) << std::endl;
}
}
Any tips on how to get this to work for objects?