So, let's say, in a class in C++, I have a variety of member variables. Structs, strings, ints, etc. etc. Could be anything. These variables can or cannot be set by the initialization of the object of this class. Given int a, float b, char c, sometimes all of them or none of them can be set. When they are set, they can be set to any possible value of the variable. I would like to find someway of setting, and determining whether or not a variable has been set without:
1) Lots of casting. I could always create a Data_Value decorator class that has a boolean, and template it to whatever the given variable is. This would require calling a_data_value.value and a_data_value.isInitialized.
2) Lots of extra Boolean variables. I'd rather not have bool a_initialized, bool b_initialized.
What I would really like to do is something like this:
Python add to a function dynamically
in C++, with any and all variables, including primitives. Tall order I know, and I'm fully expecting the pessimistic answer.
You're right. It's impossible to determine at runtime whether a primitive is "set". Some compilers will warn you for some cases of using uninitialized values, but this is not at all guaranteed.
I would use a nullable template. See http://www.codeproject.com/KB/mcpp/CNullable.aspx
Suppose you have
class Bob {
int a;
int b;
double c;
complex<double> d;
Bob () : a(), b(), c(), d() {}
};
When you create a new Bob, everything will be set to default (zero in this case).
There is no set or not set state for primitive types. They always hold some value.
If you want to rewrite Python in C++ you can.
You'd need an efficient unordered_map class keyed by string. The string would be the variable name.
Each variable value would be a class (call it a VARIANT, heh) that can hold any primitive value.
Then instead of a C++ struct you'd make your "struct" be an instance of your unordered_map aka dictionary.
If the variable name is found in the dictionary then it was set and you can return the value. If it isn't found it was never set.
If you plan to reference your dictionary keys by name from within C++ you will want to use the following for efficiency:
Instead of:
VARIANT v = dict["name"];
Use:
static const std::string name_key("name");
VARIANT v = dict[name_key];
That way instead of building a std::string containing "name" for the key lookup every time into the function, it will be done once.
Related
This question already has answers here:
C++ using struct arguments for functions instead of multiple arguments?
(6 answers)
Closed 3 years ago.
Let's say you call a function like this:
someFunc( some_int, some_float, false, "whatever text");
This doesn't look good but if alternatively I pass these by a struct / class, it won't look much better, since I will make up the struct on-the-fly like I do with function parameters.
someFunc( FuncParameters( some_int, some_float, false, "whatever text"));
Even if the struct has the parameter names in it's definition, I don't see those when I call it's constructor.
I can do this instead:
FuncParameters func_parameters;
func_parameters.some_int_data = some_int;
func_parameters.some_float_data = some_float;
func_parameters.some_text_data = "whatever text";
someFunc(func_parameters);
But if I forget the bool-data like above, then nothing will complain about it.
So why do people say that "always pass parameters in structure if there are more than X number of parameters? What am I missing?
Using structures instead of separate parameters has several advantages:
You express that data is related. By naming the struct appropriately, you can give a name to this relation.
A struct grouping related data has a chance to be reused elsewhere in your code.
Once you modify the struct (add/remove members), you don't need to adapt parameter lists. This is particularly true if you have calls through multiple functions, where the struct object is simply passed through.
Named members at the call site (soldier.speed = 3.2;) are clearer than simply passing 3.2. This applies even more to bool literals and function calls such as CreateSoldier(3.2, true, false, true).
There are also some things to keep in mind:
How you pass the struct (by value or pointer) has an effect on how much data is copied, and if you have an extra dereference at runtime.
For simple code, creating a struct only to pass it to a function can actually increase the verbosity and reduce readability of your code.
Only in C99 you have compound literals. For older versions of C it's not possible to pass temporary objects, and you need to explicitly declare a variable.
As you noticed, a well designed function can enforce initialization of all parameters; but you don't see the parameter's name at call site. For functions not taking many parameters, this can be mitigated by naming the function appropriately (e.g. SetSpeed(&soldier, 3.2)).
I think one main reason is code readability. You can read in CppCoreGuidelines
Keep the number of function arguments low
Reason Having many arguments opens opportunities for confusion. Passing lots of arguments is often costly compared to alternatives.
...
Grouping arguments into "bundles" is a general technique to reduce the
number of arguments and to increase the opportunities for checking.
Example
void f(int* some_ints, int some_ints_length); // BAD: C style, unsafe
versus
void f(gsl::span<int> some_ints); // GOOD: safe, bounds-checked
With your example
someFunc(10,20,true,"foo");
is more confusing than:
struct SomeFuncParameters
{
int max_iterations = 100;
float epsilon = 1.e-6;
bool reinit = true;
std::string name = "";
};
void someFunc(const SomeFuncParameters& parameters) {}
int main()
{
// Variation 1
//
someFunc(SomeFuncParameters());
// Variation 2
//
someFunc(SomeFuncParameters{.max_iterations = 10,
.epsilon = 1e-4,
.reinit = false,
.name = "my name"});
// Variation 3
//
SomeFuncParameters someFuncParameters;
someFuncParameters.epsilon = 1e-10;
someFunc(someFuncParameters);
}
even if you have to write a longer code.
Also note that when you use a struct to store parameters you can easily define parameter default values. You also have less code to modify if you want to add or remove some parameters as the call sites like:
someFunc(SomeFuncParameters());
someFunc(someFuncParameters);
won't be affected.
I also wrote a small C++17 lib for named optional arguments that can maybe interest you.
Traditionally, I've programmed in c++ and Java, and I'm now beginning to learn ruby.
My question then is, how do languages like ruby internally implement their array and hash data structures in such a way that they can hold any type at the same time? I know that in Java, the fact that every class is derived from object, could be one way to implement this, but I was wondering if there was another way. For example, in c++, if I wanted to implement a dynamic array that could simultaneously hold multiple types of values (of no relation), how could I do this?
To clarify, I'm not referring to generic programming or templates, as those simply create a new collection interface for a type. I'm referring to a structure such as this:
array = [1, "hello", someClass];
Most of them do roughly the same as you'd get in C++ by creating a vector (or list, deque, etc.) of boost::any, or something similar.
That is to say, they basically attach some tag to each type of object as it's stored in memory. When they store an object, they store the tag. When they read an object, they look at the tag to figure out what kind of object that is. Of course, they also handle most of this internally, so you don't have to write the code to figure out what kind of object you've just retrieved from the collection.
In case it's not clear: the "tag" is just a unique number assigned to each type. If the system you're dealing with has primitive types, it'll normally pre-assign a type number to each of them. Likewise, each class you create gets a unique number assigned to it.
To do that in C++, you'd normally create a central registry of tags. When you register a type, you receive a unique number back that you use to tag objects of that type. When a language supports this directly, it automates the process of registering types and choosing a unique tag for each.
Although this is probably the most common method of implementing such things, it's definitely not the only one. Just for example, it's also possible to designate specific ranges of storage for particular types. When you allocate an object of a given type, it's always allocated from that type's address range. When you create a collection of "objects", you're really not storing the objects themselves, but instead storing something that contains the address of the object. Since objects are segregated by address you can figure out the type of the object based on the value of the pointer.
In the MRI interpreter, a ruby value is stored as a pointer type which points to a data structure storing the class of the value and any data associated with the value. Since pointers are always the same size, (sizeof(unsigned long) usually), it is possible. To answer your question about C++, it is impossible in C++ to determine the class of an object given it's location in memory, so it wouldn't be possible unless you had something like this:
enum object_class { STRING, ARRAY, MAP, etc... };
struct TaggedObject {
enum object_class klass;
void *value;
}
and passed around TaggedObject * values. That is pretty much what ruby does internally.
There are many ways to do that :-
You can define a common interface for all the elements and make a container of those. For example:
class Common { /* ... */ }; // the common interface.
You can use container of void* :-
vector<void*> common; // this would rather be too low level.
// you have to use cast very much.
And then the best approach I think is using an Any class, such as Boost::Any :-
vector<boost::any> v;
You're looking for something called type erasure. The simplest way to do this in C++ is with boost::any:
std::vector<boost::any> stuff;
stuff.push_back(1);
stuff.push_back(std::string("hello"));
stuff.push_back(someClass);
Of course with any, you're extremely limited in what you can do with your stuff since you have to personally remember everything you put into it.
A more common use-case of heterogeneous containers might be a series of callbacks. The standard class std::function<R(Args...)> is, in fact, a type-erased functor:
void foo() { .. }
struct SomeClass {
void operator()() { .. }
};
std::vector<std::function<void()>> callbacks;
callbacks.push_back(foo);
callbacks.push_back(SomeClass{});
callbacks.push_back([]{ .. });
Here, we're adding three objects of different types (a void(*)(), a SomeClass, and some lambda) to the same container - which we do by erasing the type. So we can still do:
for (auto& func : callbacks) {
func();
}
And that will do the right thing in each of the three objects... no virtuals needed!
Others have explained ways you can do this in C++.
There are various ways to solve this problem. To answer your question about how does languages such as Ruby solve this, without going into details of exactly how Ruby solves it, they use a structure that contains type information. For example, we could do that in C++ something like this:
enum TypeKind { None, Int, Float, String }; // May need a few more?
class TypeBase
{
protected:
TypeKind kind;
public:
TypeBase(TypeKind k) : kind(k) { }
virtual ~TypeBase() {};
TypeKind type() { return kind; }
};
class TypeInt : public TypeBase
{
private:
int value;
public:
TypeInt(int v) : value(v), TypeBase(Int) {}
};
class TypeFloat : public TypeBase
{
private:
double value;
public:
TypeFloat(double v) : value(v), TypeBase(Float) {}
};
class TypeString : public TypeBase
{
private:
std::string value;
public:
TypeString(std::string v) : value(v), TypeBase(String) {}
};
(To make it useful, we probably need some more methods for the TypeXxx class, but I don't feel like typing for another hour... ;) )
And then somewhere, it determines the type, e.g.
Token t = getNextToken();
TypeBase *ty;
if (t.type == IntegerToken)
{
ty = new(TypeInt(stoi(t.str));
}
else if (t.type == FloatToken)
{
ty = new(TypeFloat(stod(t.str));
}
else if (t.type == StringToken)
{
ty = new(TypeString(t.str));
}
Of course, we'd also need to deal with variables and various other scenarios, but the essence of it is that the language can keep track of (and sometimes mutate) the value that is stored.
Most languages in the general category where Ruby, PHP, Python, etc are, will have this sort of mechanism, and all variables are stored in some sort of indirect way. The above is just one possible solution, I can think of at least half a dozen other ways to do this, but they are variations on the theme of "store data together with type information".
(And by the way, boost::any also does something along the lines of the above, more or less....)
In Ruby, the answer is rather simple: that array doesn't contain values of different types, they are all of the same type. They are all objects.
Ruby is dynamically typed, the idea of an array that is statically constrained to only hold elements of the same type doesn't even make sense.
For a statically typed language, the question is, how much do you want it to be like Ruby? Do you want it to be actually dynamically typed? Then you need to implement a dynamic type in your language (if it doesn't already have one, like C♯’s dynamic).
Otherwise, if you want a statically typed heterogenous list, such a thing is usually called an HList. There's a very nice implementation for Scala in the Shapeless library, for example.
I am newbie to C++, and want to understand what is the difference between saying
typedef enum stateUpdateReasonCode
{
a=1,
b=2,
c=3
} StateUpdateReasonCode;
and
struct StateUpdateReasonCode
{
a=1,
b=2,
c=3
};
What is difference between them ? Wy would we use one over another ?
Kind Regards
An enum and a struct are totally different concepts, fulfilling different purposes.
An enum lets you declare a series of identifiers for use in your code. The compiler replaces them with numbers for you. It's often useful for making your code more readable and maintainable, because you can use descriptive names without the performance penalty of string comparisons. It can also make the code less bug-prone because you don't have to keep writing in specific numbers everywhere, which could go wrong if a number changes.
A struct is a data structure. At its simplest, it contains zero or more pieces of data (variables or objects), grouped together so they can be stored, processed, or passed as a single unit. You can usually have multiple copies (or instances) of it. A struct can be a lot more complex though. It's actually exactly the same as a class, except that members are public by default instead of private. Like a class, a struct can have member functions and template parameters and so on.
One of the vital difference between structs and enums is that an enum doesn't exist at run-time. It's only for your benefit when you're read/writing the code. However, instances of structs (and classes) certainly can exist in memory at runtime.
From a coding standpoint, each identifier in an enum doesn't have its own type. Every member within a struct must have a type.
The first compiles, the second does not.
Your struct declaration is invalid. In plain C struct are so called record types, they contain a set of values (each with it's own type). In C++ this capability is expanded and a struct is basically equivalent to a class. The struct can now have base classes, member functions, access specifiers, conversion operators, operator overloads and so on.
An enum is an enumeration type: it describes a finite set of states. In C and C++ the fact that enum values are convertible to integers is more or less a leaking abstraction.
They are fundamentally different.
Struct
For a struct these values are defaults (only for C++ 11 onwards) for the data structure. A "struct" is a structure of data, for example:
struct Car
{
float enginesize = 0.0f;
char modelname[100];
};
You would assign these values after you've declared a variable of the type Car etc:
{
Car brum = {1.0f}; // Specify a a size: don't use default
Car zoom; // Will default to 0.0 as specified in the struct
}
Without a default value it will undefined (something random).
Enum
An enumeration, however, is renamed numeric values: it's a very handy way of naming numeric constants. e.g.
enum EngineType
{
Petrol,
Diesel,
Electric,
LPG = 34 // NB assigning values is optional
};
enum work like the constants where you want to specify the the value with a word. Like for the days of week one want that sun = 0, mon = 1 and so on. In this case enum can be used.
struct is totally different from the enum. It can be seen analogues to the class in c++ or any other programming language. structure is a user defined data type which can be used to store the info. Like in address different fields can be there street , zip code etc.
the first one compiles as it stores the value of an enum and second one does not as struct variable data members values can be assigned by creating a struct variable.
I have a header that defines c style structs that are to be passed over a boundary on a c++ DLL. This header and DLL will potentially be used by c++, java and c applications. I want to initialise these structs in someway that allows the user to specify a subset of the parameters, and the rest will be given defaults.
I was thinking of creating a series of initialise functions in the header, which would take a reference to the struct they will initialise along with parameters for all members that can be set. The "initialise" functions would use overloading (based on the struct reference passed in) to ensure the correct one was called. I also planned on using default parameters to set the defaults. The functions would have to be gobal i guess.
Is this a good approach? Is there a better alternative? thanks
You could add a function that returns a default initialized structure :
struct abc
{
int a;
float b;
char c;
};
abc GetDefaultAbc()
{
const abc def = { 1,2.0,3 };
return def;
};
Before I was trying to map my classes and namespaces, by using static calls I succeded and now I need to map the functions of my classes because they will be used dynamically.
Firstly I was thinking to hardcode in the constructor so I can assign a std:map with the string of the name of function pointing to the function itself.
for example:
class A{
int B(){
return 1;
}
};
int main(){
A *a = new A();
vector<string, int (*)()> vec;
vector["A.B"] = a.B;
}
By that I have mapped the function B on A class, I know that I only mapped the function the instance and thats B is not static to be globally mapped.
But thats what I need, at somepoint someone will give me a string and I must call the right function of an instance of a class.
My question is if I only can do that by hardcoding at the constructor, since this is a instance scope we are talking or if there is somehow a way to do this in the declaration of the function, like here for namespaces and classes:
Somehow register my classes in a list
If I understand you correctly, you want your map to store a pointer that can be used to call a member function on an instance, the value being chosen from the map at run time. I'm going to assume that this is the right thing to do, and that there isn't a simpler way to solve the same problem. Quite often when you end up in strange C++ backwaters it's a sign that you need to look again at the problem you think you have, and see whether this is the only way to solve it.
The problem with using an ordinary function pointer is that a non-static member function is not an ordinary function. Suppose you could point to a member function with an ordinary function pointer, what would happen when you dereferenced that pointer and called the function? The member function needs an object to operate on, and the syntax doesn't provide a way to pass this object in.
You need a pointer to member, which is a slightly obscure feature with relatively tricky syntax. While an ordinary pointer abstracts an object, a pointer to member abstracts a member on a class; the pointer specifies which class member should be called, but not which object to obtain the member from (that will be specified when the pointer is used). We can use it something like this:
class B;
class A
{
B some_function()
{ /* ... */ }
};
B (A::* myval)() = A::some_function;
Here myval is a variable that indicates one of the members of class A, in this case the member some_function (though it could point to any other member of A of the same type). We can pass myval round wherever we want (e.g. storing it in an STL container, as in your example) and then when we want to call the function, we specify the instance it should be called on in order to locate the function:
A some_a;
B newly_created_b = (some_a.*myval)();
This works for a particular case, but it won't solve your general issue, because member pointers contain the class they refer to as part of the definition. That is, the following two variables are of entirely different types:
B (Foo::* first_variable)() = Foo::some_function;
B (Bar::* second_variable)() = Bar::some_function;
Even though both functions can produce a B when called without arguments, the two values operate on different classes and therefore you can't assign a value of one type to a variable of the other type. This of course rules out storing these different types in a single STL container.
If you're committed to storing these in a container, you'll have to go with a functor-based solution like Charles Salvia proposes.
If I understand you correctly, you're going to have a class like:
struct Foo
{
int bar();
};
And the user will input a string like "Foo::bar", and from that string you need to call the member function Foo::bar?
If so, it's rather awkward to code a flexible solution in C++, due to the static type system. You can use an std::map where the key is a string, and the value is a member function pointer, (or std::mem_fun_t object), but this will only work on a single class, and only on member functions with the same signature.
You could do something like:
#include <iostream>
#include <map>
#include <functional>
struct Foo
{
int bar() { std::cout << "Called Foo::bar!" << std::endl; }
};
int main()
{
std::map<std::string, std::mem_fun_t<int, Foo> > m;
m.insert(std::make_pair("Foo::bar", std::mem_fun(&Foo::bar)));
Foo f;
std::map<std::string, std::mem_fun_t<int, Foo> >::iterator it = m.find("Foo::bar");
std::mem_fun_t<int, Foo> mf = it->second;
mf(&f); // calls Foo::bar
}
just found(using google) a topic to the same question I had with an answer.
What is the simplest way to create and call dynamically a class method in C++?
I didn't try it yet but makes sense, I will ask again later if it doesn't work
ty!
Joe
I must call the right function of an instance of a class.
You need to call a specific method on an existing instance, or you need to create an instance of the appropriate type and call the method?
If it's the former, then you need a std::map or similar that lets you look up instances from their names.
If it's the latter, that's basically what serialization frameworks need to do in order to create the correct type of object when de-serializing, the object that knows how to read the next bit of data. You might take a look at how the Boost serialization library handles it:
boost.org/doc/libs/1_40_0/libs/serialization/doc/serialization.html
Are you doing this in some kind of tight loop where you need the efficiency of a good map? If so, then member function pointers (as you linked to above) is a good way to go. (At least it is after you work around the problem #Tim mentioned of keeping member function pointers to different types in the same collection ... let the language abuse begin!)
On the other hand, if this is in code that's user-driven, it might be more legible to just be totally uncool and write:
if( funcName=="A.b" )
{
A a;
a.b();
} else
// etc etc etc
For the higher-performace case, you can supplement the same approach with a parse step and some integer constants (or an enum) and use a switch. Depending on your compiler, you might actually end up with better performance than using member function pointers in a map:
switch( parse(funcName) )
{
case A_b:
{
A a;
a.b();
}
break;
}
(Of course this breaks down if you want to populate your list of possibilities from different places ... for example if each class is going to register itself during startup. But if you have that kind of object infrastructure then you should be using interfaces instead of pointers in the first place!)