memcpy and std components like map: runtime failer - c++

I have an old C library I try to modify. There is a line like:
memcpy(&m_agents[idx].params, params, sizeof(dtCrowdAgentParams));
And ofcourse C stule pod like values and structs get copied. But I tried to add to params.some_struct.some_inner_map_field std::map and it does not get initialised on memcpy.
So I wonder how to copy my map keeping it alive? (if possible not extending methods of params and params.some_struct)

I would need to see the full definition of the struct to be sure, but this should work:
m_agents[idx].params = *params;
For POD types, it will do the same thing as memcpy. For non-POD types, it will call their assignment operator.

Replacing it with
m_agents[idx].params = *params;
will correct that instance. However, it's reasonable to suppose that the C library you are working with is assuming POD throughout and so you will need to check the whole codebase to ensure it's not doing anything that will break things elsewhere.
Are your maps mutable within the library or can you treat them as constant while the library is handling the data? If you can treat them as constant consider passing a handle, or pointer, to you map into the library instead of including the map itself in the parameter struct.

Related

Creating interface for c++ dll

I have a class that is constructed with a path to a text file. It parses the text file and stores a lot of data in various vectors and maps as its members. I'd like to share the class as a dll with users of different versions of MSVS (something that's new to me).
My original implementation when it was just for me returned the STL containers directly. After reading, my understanding is that this is dangerous because different compilers or different versions of the same compiler can easily implement the containers differently. One solution I saw was to explicitly instantiate any templates you were using and export them as well. I also had strings so I'd need to instantiate and export that since a std::string is actually an alias for a more complex template. However, even if I went that route it appears there's nothing I can do about exporting maps.
What I've done now is that instead of giving the user access to the containers, I have accessor functions that take an index (or a key for the maps, or a key and index for a vector of maps I've got) and fetch the value. All my parameters and return values are primitive types, including const char* for the strings.
Am I understanding the problem correctly, and is this a reasonable approach to it? Do I need to worry about the integral primitives in c++ not being strictly defined in the standard? I suppose I could use the std-defined integral types as well. One issue is that the user won't be able to iterate over the containers or check size. I could provide the size as a member(all the vectors are the same size), and then I guess it'd just be up to the user to provide their own vector and fill it if they want the other vector functionality.

is it possible to set the default value of std::tr1::tuple?

(i'm using Visual C+++ 2010)
suppose i have defined a tuple like this:
typedef std::tr1::tuple<
int //i want to set its default value to 9
, double //i want to set its default value to 3.3
, int //i want to set its default value to 2
, double //i want to set its default value to -7.2
> Mytuple;
i can do that in a struct. but i wonder if it is possible to do that in std::tr1::tuple.
Besides, i want to know when shoud i use std::tr1:tuple or struct?
anyone can help me?
A tuple is not a magical replacement for a struct. Their purposes are very different. A struct is, first and foremost, a language construct. A tuple is a library construct.
Structs get to have default values because the language says that you can write constructors to give them default values. The language then takes responsibility to call that constructor to initialize the struct. tuple, as a library construct, has no such capabilities, anymore than you can give std::vector<T> a default T that it will always automatically use. You can provide initial values for each member, but you can't give it defaults.
And if you think about it, you wouldn't want to. Imagine if someone could say that every tuple<int, float> was always created with 3 and 54.221. Even if some other code created it that knew nothing about this rule, it would have to be followed, (just as constructors for the type are used everywhere that type is used). Remember: every tuple<int, float> is the same type.
Really, a tuple is a substitute for the inability to perform reflection on a struct and do compile-time iteration over its members. The other main reason they exist is to be able to have compile-time dynamic structures (that is, the ability to create aggregates of types based on compile-time arguments, rather than a static list directly written into a file).
So unless you need to use std::tie (for effectively returning multiple values), iteration over members (ie: call some template function for each member of an object), or some similar specialized code, you should be using a struct.

unique type identifiers across different C++ programs

Is there a way to automatically (i.e. not by hand) assign unique identifiers to types in different programs that share common source code? I'd need one program to tell another "use type X" and the other would know what that "X" meant. Of course, they would (partially) share the source code, as you cannot construct types in runtime, I just want an automatic way of constructing a map from some sort of identifiers (integers or strings) to e.g. factory functions returning objects of given type.
An obvious choice I'd go for is result of name() in std::type_info, but as I understand, that is not even guaranteed to be different across types, and using address of std::type_info instances is certainly not going to work across programs.
I cannot use C++11, but can use Boost for this.
I just want an automatic way of constructing a map from some sort of
identifiers (integers or strings) to e.g. factory functions returning
objects of given type.
Not going to happen, not within Standard C++, anyway.
You could take a look at boost serialisation. It automatically generates unique ids for polimorphic classes and allows the explicit registration of non polimorphic ones.

What type can hold member-function-pointers of difference classes in C++?

I need an array to hold member-function-pointers of different classes. How can I define the array?
The code should look like this:
arr[0] = &CMyClass::FuncX;
arr[1] = &CYourClass::FuncY;
arr[2] = &CHerClass::FuncZ;
I tried void*, but it doesn't work.
You can't; they are all different types and arrays are homogeneous.
Regardless what the arguments are or what the return value is, there is an implicit this which is unique to the class type. The type of a class member pointer is:
return_value (class_type::*)(parameters);
As you can see, because they belong to different classes they will always be a different type. Even if it were the same class, the return_value and parameters would have to be consistent to create an array, otherwise you'd still have different types.
What's the bigger picture? Boost.Bind with Boost.Function comes to mind. Also, virtual functions may solve your problem.
As others have pointed out, you can't store pointers to different kinds of functions directly. You might want to look at the Command template, e.g., from Modern C++ Design, which at least lets you put different invokable "things" (pointers or smart pointers to functions, functors, member functions) into a single thing.
On its own, that probably won't be sufficient -- you'll (apparently) end up with the template instantiated over different types, which produces different types. Those types will all use the same syntax, but won't all go into an array (which demands a single type).
Depending on your constraints, (compile-time vs. run-time indexing, in particular) you may be able to use a Boost::tuple to store a collection of command objects. You can treat that a bit like an array, using numeric indexing to get to an individual item. Unlike a normal array, however:
the syntax is a bit ugly, and
The indexing has to be done at compile-time (using compile-time constants).
Without know the parameters or return types of the function its hard to define them for you look at this page to get the gist of it or post the declaration of the functions.
Others have noted why you can't do this. But even if you could, what would you be able to do with it. In order to call a member function pointer, you need to an object of the appropriate type to call it on. So you would need to know the type of each of the member function pointers. You need to take a step back and figure out what it is that you are trying to accomplish.

How to store variant data in C++

I'm in the process of creating a class that stores metadata about a particular data source. The metadata is structured in a tree, very similar to how XML is structured. The metadata values can be integer, decimal, or string values.
I'm curious if there is a good way in C++ to store variant data for a situation like this. I'd like for the variant to use standard libraries, so I'm avoiding the COM, Ole, and SQL VARIANT types that are available.
My current solution looks something like this:
enum MetaValueType
{
MetaChar,
MetaString,
MetaShort,
MetaInt,
MetaFloat,
MetaDouble
};
union MetaUnion
{
char cValue;
short sValue;
int iValue;
float fValue;
double dValue;
};
class MetaValue
{
...
private:
MetaValueType ValueType;
std::string StringValue;
MetaUnion VariantValue;
};
The MetaValue class has various Get functions for obtaining the currently stored variant value, but it ends up making every query for a value a big block of if/else if statements to figure out which value I'm looking for.
I've also explored storing the value as only a string, and performing conversions to get different variant types out, but as far as I've seen this leads to a bunch of internal string parsing and error handling which isn't pretty, opens up a big old can of precision and data loss issues with floating point values, and still doesn't eliminate the query if/else if issue stated above.
Has anybody implemented or seen something that's cleaner to use for a C++ variant data type using standard libraries?
As of C++17, there’s std::variant.
If you can’t use that yet, you might want Boost.Variant. A similar, but distinct, type for modelling polymorphism is provided by std::any (and, pre-C++17, Boost.Any).
Just as an additional pointer, you can look for “type erasure”.
While Konrad's answer (using an existing standardized solution) is certainly preferable to writing your own bug-prone version, the boost variant has some overheads, especially in copy construction and memory.
A common customized approach is the following modified Factory Pattern:
Create a Base interface for a generic object that also encapsulates the object type (either as an enum), or using 'typeid' (preferable).
Now implement the interface using a template Derived class.
Create a factory class with a templateized create function with signature:
template <typename _T> Base * Factory::create ();
This internally creates a Derived<_T> object on the heap, and retuns a dynamic cast pointer. Specialize this for each class you want implemented.
Finally, define a Variant wrapper that contains this Base * pointer and defines template get and set functions. Utility functions like getType(), isEmpty(), assignment and equality operators, etc can be appropriately implemented here.
Depending on the utility functions and the factory implementation, supported classes will need to support some basic functions like assignment or copy construction.
You can also go down to a more C-ish solution, which would have a void* the size of a double on your system, plus an enum for which type you're using. It's reasonably clean, but definitely a solution for someone who feels wholly comfortable with the raw bytes of the system.
C++17 now has std::variant which is exactly what you're looking for.
std::variant
The class template std::variant represents a type-safe union. An
instance of std::variant at any given time either holds a value of one
of its alternative types, or in the case of error - no value (this
state is hard to achieve, see valueless_by_exception).
As with unions, if a variant holds a value of some object type T, the
object representation of T is allocated directly within the object
representation of the variant itself. Variant is not allowed to
allocate additional (dynamic) memory.
Although the question had been answered for a long time, for the record I would like to mention that QVariant in the Qt libraries also does this.
Because C++ forbids unions from including types that have non-default
constructors or destructors, most interesting Qt classes cannot be
used in unions. Without QVariant, this would be a problem for
QObject::property() and for database work, etc.
A QVariant object holds a single value of a single type() at a time.
(Some type()s are multi-valued, for example a string list.) You can
find out what type, T, the variant holds, convert it to a different
type using convert(), get its value using one of the toT() functions
(e.g., toSize()) and check whether the type can be converted to a
particular type using canConvert().