Structure of structures - c++

I'm making a global struct of structures by declaring them on the header file file this:
const int Numberof=8;
struct FP
{
std::string callsign;
std::string de_airport;
std::string ar_airport;
std::string aircraft_type;
int trueairspeed;
std::vector<string> route;
std::vector<int> FL_route;
int current_state;
std::string current_WP;
std::string hour_lastWP;
std::string next_WP;
std::string hour_nextWP;
};
struct FP FP_list[Numberof];
Problem is, I defined the Numberof to 8 just to make it through my case. In the future that value is going to vary and i won't know its value until way later. What I'm interested in is a way of adding an instance to FP_list every time FP_listis called. Is there any way of doing it?
I know that making std::vector <FP> FP_listand then using vector::push_back is a solution, but since I don't know when and where my program ends I won't be able to swap my vector properly. Is that a problem, not calling .swap(Numberof)?
Edit: Oh and also, what I said about FP_list.swap(Numberof) applies to my objects of structure FP. Will it be a problem if I don't swap route and FL_route?

You can use std::vector<FP> FP_list and then using vector::push_back to add elements to it. Based on the structures given, there's no need to do swap anywhere (or even an option to do so).
swap is to swap the contents of two different vectors of the same type, which you don't have.
If you read somewhere that you should use swap after finishing using a vector, you may have misunderstood the scenario described. I can't come up with a scenario where it would be useful off the top of my head, but it does not relate to when the program finishes (if you consider that swap just swaps the content of 2 vectors, the other vector will still be left with the data, so whether it's in the one or the other, it doesn't really matter - it still needs to be freed).

For future reference, std::vector<FP> FP_list was the solution and in the function where I fill the structures, the solution to add one element do the vector each time I call the function is:
FP_List.push_bak(FP())
That's exactly what i was looking for

Related

Move large member object out of class?

Background/Example:
I currently have a class like the following:
class Element {
Large l1;
OtherLarge l2;
Small s1;
VerySmall s2;
};
where Large and OtherLarge are relatively big (~80 bytes) whereas Small and VerySmall are fairly small (~4 to 16 Byte).
On these elements, I operate in two ways:
sorting them in various ways. During this, only members s1 and s2 are accessed/needed.
combining the large members in various way (e.g. matrix-matrix multiplication).
The second class of operations is already fairly fast and can be parallelised easily, hence I’d like to speed up the first class of operations more. Comparing with another class Element2 where I replaced the two big data members by 8-byte integers doing nothing tells me that if I can somehow replace the direct data members l1 and l2 by pointers of one sort or another to dynamically-allocated elements elsewhere, I’ll already get a big win.
For reference, all member types have both copy and move constructors and can be both copied and moved, but moving them is much much cheaper. Large and OtherLarge also allocate a lot of memory by themselves, so allocating a bit more isn’t necessarily horrible.
Concrete question
Is it possible, and if so, what is the best way, to replace a direct member object of a class with a pointer to a dynamically-allocated object elsewhere; preserving the behaviour of a direct member as closely as possible w.r.t construction, destruction, member variable access etc? If I use a std::unique_ptr<Large> naively, I assume I’ll have to dereference it half the time/take care of copying specially? Ideally I’d like the new member object to behave just as if the old, big member object was still there.
unique_ptr will not solve your issue as sorting may involve copying (for swapping). I am fairly certain that flyweight pattern can solve your issues. Here is a simple implementation:
class Element_data {
public:
large l1,l2;
};
std::vector<Element_data> data;
class Element {
public:
small s1, s2;
int data_ind;
large &GetLarge1() {
assert(data_ind>=0 && data_ind<data.size);
return data[data_ind].l1;
}
};
std::vector<Element> elements;
...
std::sort(elements.begin(), elements.end(), &mysortfn);
Why not use pointers? They may get invalidated if you add new members to the data vector. Also this approach allows you to keep your data together so it might get loaded into cache easier.
Additional points:
If you are deleting an element for good, you should erase the data as well.
Adding new member is quite simple
While sorting or some other operations, it is safe to have more than one Element to point to the same data
Edit: Just to make sure you won't run into problems if it is not clear, destructor of Element should not destroy data. You can provide custom deleter for this. The best approach would be to develop a container that can do this, erase the element and data with erase function.

How should I pass read only vectors in functions in C++?

How should I pass read only vectors in functions in C++?
One way to do it is the usual way as const&
const vector<string>& input
but I was wondering maybe I should do it this way instead:
const vector<const string&>& input
I am not sure which one is better. Basically I want to pass
a vector only for reading purposes, and I want to do it efficiently,
and avoid unnecessary copies.
A vector of references is not possible in C++ and wont compile at all (as a reference may be implemented without storage).
Besides that even if it would be possible you cant simply convert a std::vector<T> to a std::vector<T&> or std::vector<T*> (which is possible).
Now asides from the techinally aspects: There is no need for this. It would actually create more overhead. If your passing a reference to your vector, its data is completely left untouched. The only operation done is the PUSH of the address of the vector onto the stack.
So go with your first solution

Initializing std::vector of std::string

While working in a project with some legacy code i found this function:
std::vector<std::string> Object::getTypes(){
static std::string types [] = {"type1","type2", "type3"};
return std::vector<std::string> (types , types +2);
}
I would probably have written this as:
std::vector<std::string> Object::getTypes(){
std::vector<std::string> types;
types.push_back("type1");
types.push_back("type2");
types.push_back("type3");
return types;
}
Is this merely a style choice or is there something I'm missing? Any help would be greatly appreciated. Sorry if this is too basic.
Update:
Actually found different classes that override the same method do it one way or the other, so It's even more ambiguous. I would make them all the same but would prefer the better approach, if there is one.
Edit
Please note that the above legacy code is incorrect because it initializes the vector with only the first two elements of the array. However, this error has been discussed in the comments and thus should be preserved.
The correct initialization should have read as follows:
...
return std::vector<std::string> (types, types + 3);
...
If you have a C++11 capable compiler and library, returning an initializer list should be enough:
std::vector<std::string> Object::getTypes(){
return {"type1","type2", "type3"};
}
The code you found is more efficient (because types[] is only allocated once and push_back can/will cause re-allocations). The difference though is marginal, and unless you call getTypes in a (relatively big) loop it shouldn't matter at all (and probably it won't matter much even when you do call it in a big loop).
As such, unless it creates a concrete performance problem, it's a style choice.
Basically it's a style choice. I'd probably do something more like
std::vector<std::string> Object::getTypes(){
static std::string types [] = {"type1","type2", "type3"};
return std::vector<std::string> (types,
types + (sizeof(types)/sizeof(std::string)) );
}
which lets you change the number of things in types, without having to remember to update the count in the next line.
The array types in the first example is declared static. This means it only exists once in memory. So there are three options for what to return and they live in static memory. Then, when you create the vector to return, you are able to allocate it's memory in one shot by passing the beginning and ending of the array as iterators.
By doing it this way, you don't have successive calls to push_back which means the vector won't have to reallocate its internal block of memory.
Also, when the vector is constructed as part of the return call, older compilers will have an easier time of doing return value optimization.
One reason I like to use this style of initialization with iterators (and C++11's uniform initialization and initializer lists) is that it helps separating data from code.
Repeating push_back a lot of times feels bad because I desperately need to refactor that. Also, when you really just need to initialize the container with data, then you want to see a list of the data, and not really code that generates data. The method you found in the original version matches that principle better.

Is it unefficient to use a std::vector when it only contains two elements?

I am building a C++ class A that needs to contain a bunch of pointers to other objects B.
In order to make the class as general as possible, I am using a std::vector<B*> inside this class. This way any number of different B can be held in A (there are no restrictions on how many there can be).
Now this might be a bit of overkill because most of the time, I will be using objects of type A that only hold either 2 or 4 B*'s in the vector.
Since there is going to be a lot of iterative calculations going on, involving objects of class A, I was wondering if there is a lot of overhead involved in using a vector of B's when there are only two B's needed.
Should I overload the class to use another container when there are less than 3 B present?
to make things clearer: A are multipoles and B are magnetic coils, that constitute the multipoles
Premature optimization. Get it working first. If you profile your application and see that you need more efficiency (in memory or performance), then you can change it. Otherwise, it's a potential waste of time.
I would use a vector for now, but typedef a name for it instead of spelling std::vector out directly where it's used:
typedef std::vector vec_type;
class A {
vec_type<B*> whatever;
};
Then, when/if it becomes a problem, you can change that typedef name to refer to a vector-like class that's optimized for a small number of contained objects (e.g., does something like the small-string optimization that's common with many implementations of std::string).
Another possibility (though I don't like it quite as well) is to continue to use the name "vector" directly, but use a using declaration to specify what vector to use:
class A {
using std::vector;
vector<B*> whatever;
};
In this case, when/if necessary, you put your replacement vector into a namespace, and change the using declaration to point to that instead:
class A {
using my_optimized_version::vector;
// the rest of the code remains unchanged:
vector<B*> whatever;
};
As far as how to implement the optimized class, the typical way is something like this:
template <class T>
class pseudo_vector {
T small_data[5];
T *data;
size_t size;
size_t allocated;
public:
// ...
};
Then, if you have 5 or fewer items to store, you put them in small_data. When/if your vector contains more items than that fixed limit, you allocate space on the heap, and use data to point to it.
Depending a bit on what you're trying to optimize, you may want to use an abstract base class, with two descendants, one for small vectors and the other for large vectors, with a pimpl-like class to wrap them and make either one act like something you can use directly.
Yet another possibility that can be useful for some situations is to continue to use std::vector, but provide a custom Allocator object for it to use when obtaining storage space. Googling for "small object allocator" should turn up a number of candidates that have already been written. Depending on the situation, you may want to use one of those directly, or you may want to use them as inspiration to write your own.
If you need an array of B* that will never change its size, you won't need the dynamic shrinking and growing abilities of the std::vector.
So, probably not for reasons of efficiency, but for reasons of intuition, you could consider using a fixed length array:
struct A {
enum { ndims = 2 };
B* b[ndims];
};
or std::array (if available):
struct A {
std::array<B*, 2> b;
};
see also this answer on that topic.
Vectors are pretty lean as far as overhead goes. I'm sure someone here can give more detailed information about what that really means. But if you've got performance issues, they're not going to come from vector.
In addition I'd definitely avoid the tactic of using different containers depending on how many items there are. That's just begging for a disaster and won't really give you anything in return.

How do I return hundreds of values from a C++ function?

In C++, whenever a function creates many (hundreds or thousands of) values, I used to have the caller pass an array that my function then fills with the output values:
void computeValues(int input, std::vector<int>& output);
So, the function will fill the vector output with the values it computes. But this is not really good C++ style, as I'm realizing now.
The following function signature is better because it doesn't commit to using a std::vector, but could use any container:
void computeValues(int input, std::insert_iterator<int> outputInserter);
Now, the caller can call with some inserter:
std::vector<int> values; // or could use deque, list, map, ...
computeValues(input, std::back_inserter(values));
Again, we don't commit to using std::vector specifically, which is nice, because the user might just need the values in a std::set etc. (Should I pass the iterator by value or by reference?)
My question is: Is the insert_iterator the right or standard way to do it? Or is there something even better?
EDIT: I edited the question to make it clear that I'm not talking about returning two or three values, but rather hundreds or thousands. (Imagine you have return all the files you find in a certain directory, or all the edges in a graph etc.)
Response to Edit: Well, if you need to return hundreds and thousands if values, a tuple of course would not be the way to go. Best pick the solution with the iterator then, but it's best not use any specific iterator type.
If you use iterators, you should use them as generic as possible. In your function you have used an insert iterator like insert_iterator< vector<int> >. You lost any genericity. Do it like this:
template<typename OutputIterator>
void computeValues(int input, OutputIterator output) {
...
}
Whatever you give it, it will work now. But it will not work if you have different types in the return set. You can use a tuple then. Also available as std::tuple in the next C++ Standard:
boost::tuple<int, bool, char> computeValues(int input) {
....
}
If the amount of values is variadic and the type of the values is from a fixed set, like (int, bool, char), you can look into a container of boost::variant. This however implies changes only on the call-side. You can keep the iterator style of above:
std::vector< boost::variant<int, bool, char> > data;
computeValues(42, std::back_inserter(data));
You could return a smart pointer to a vector. That should work and no copy of the vector will be made.
If you don't want to keep the smart pointer for the rest of your program, you could simply create a vector before calling the function, and swap both vectors.
Actually, your old method of passing in the vector has a lot to recommend it -- it's efficient, reliable, and easy to understand. The disadvantages are real but don't apply equally in all cases. Are people really going to want the data in an std::set or list? Are they really going to want to use the long list of numbers without bothering to assign it to a variable first (one of the reasons to return something via 'return' rather than a parameter)? Being generic is nice, but there is a cost in your programming time that may not be redeemed.
If you ever have a group of objects, chances are you have at least a few methods that work on that group of objects (otherwise, what are you doing with them?)
If that's the case, it would make sense to have those methods in a class that contain both said objects and methods.
If that makes sense and you have such a class, return it.
I virtually never find myself thinking that I wish I could return more than one value. By the fact that a method should only do one small thing, your parameters and return values tend to have a relationship, and so are more often than not deserving of a class that contains them, so returning more than one value is rarely interesting (Maybe I wished for it 5 times in 20 years--each time I refactored instead, came up with a better result and realized my first attempt was sub-standard.)
One other option is boost::tuple: http://www.boost.org/doc/libs/1_38_0/libs/tuple/doc/tuple_users_guide.html
int x, y;
boost::tie(x,y) = bar();
A stadard container works for homogenous objects 9which you can return).
The standard library way is to abstract an algorithm from the container and use iterators to bridge the gap between.
If you need to pass more than a single type think of structs/classes.
My question is: Is the insert_iterator the right or standard way to do it?
Yes. Otherwise, if you are not going to have at least as many elements in your container as there will be computed values. This is not always possible, specially, if you want to write to a stream. So, you are good.
Your example with insert_iterator won't work, because insert_iterator is a template requiring a container for a parameter. You could declare it
void computeValues(int input, std::insert_iterator<vector<int> > outputInserter);
or
template<class Container>
void computeValues(int input, std::insert_iterator<Container> outputInserter);
The first will tie you back to a vector<int> implementation, without any obvious advantages over your initial code. The second is less restrictive, but implementing as a template will give you other constraints that might make it a less desirable choice.
I'd use something like
std::auto_ptr<std::vector<int> > computeValues(int input);
{
std::auto_ptr<std::vector<int> > r(new std::vector<int>);
r->push_back(...) // Hundreds of these
return r;
}
No copying overhead in the return or risk of leaking (if you use auto_ptr correctly in the caller).
I'd say your new solution is more general, and better style. I'm not sure I'd worry too much about style in c++, more about usability and efficiency.
If you're returning a lot of items, and know the size, using a vector would allow you to reserve the memory in one allocation, which may or may not be worth it.