C++ static multi array wrapper - c++

Old c-style static arrays can be quite bothersome when passed as arguments, or returned as value. For that, the new std::array is quite convenient.
However for multi-array, there is nothing in std:: and the boost::multi_array isn't just statically allocated.
Of course, I could do, say,
std::array<std::array<int,3>,2> my_array;
but I find sligthly long and it corresponds to the inverted built-in declaration
int my_array[2][3];
I am just wondering if there is already some "library" coding such a concept (bi-dimensional or any-dimensional)
(which for the latter, if I am correct, must use some variadic template for typing e.g.
multi_array<int,3,4> A;
multi_array<int,3,5,8> B;
multi_array<int,4,7,8,9,8,3> C; //this one being quite rare though
)
EDIT : sorry about the first post, I didn't test

It might be overkill for your application, but I have worked with the Eigen library and think it's family of Matrix template classes might work for you. An example:
Eigen::Matrix<float, 3, 2> a;
a(1,0) = 1.1;
a(0,1) = 17.5;
EDIT 1: Oops, I don't know for sure if it supports N-dimensional matrices. But for 2-dimensional ones I know it is good.
I think you can use typedefs, either with Eigen or with std::array, to make your types more readable.

Related

Why ISO C++ forbids returning arrays?

I don't see any logical reason. I mean you can easily overcome the requirement by using a structure containing an array member like this:
template <size_t n>
struct arr { int d[n]; };
auto fnReturningArray()
{
return arr<3>{0, 1, 2};
};
Which will behave the exact same way as if the array is directly returned with the small difference that you should first access the structure member 'd' to use it. Also the standard itself have added similar functionality by the 'std::array' type. So it seems that it is implementation possible. Why then ISO C++ have forbidden this action? Maybe legacy code compatibility (but I can hardly believe this is the case as with the other new things added it is long gone, like for example the new meaning of the 'auto' keyword).
Beside the fact that the standard doesn't allow it, and the historical reasons that could explain it, the issue is syntactic:
Imagine it would be permitted : how would you distinguish the naming of the whole array, vs the array address, vs a single element:
auto fnReturningArray()
{
int a[3] = {0, 1, 2};
return a; // what is meant here ? the address of the array ? or the whole array ?
};
If you'd change the meaning of existing rules (such as tating that a would be the whole array), you would have huge problems with legacy code.
The answer as I see it, is twofold:
Compatibility with C. C doesn't work this way. Why? No idea. C never was very logical to begin with in various aspects.
C++ prefers library features over language features. Seeing that C++98 was the first standard, and it mostly copied the basics from C (see point 1), this was corrected in the first major revision, C++11, which introduces the library type std::array, which, as a pure and simple library feature, solves all the abhorrent quirks that C-style arrays entail.
To summarise: even though it might make sense to have proper value semantics for arrays, it will never happen, because the apparent deficiency can be solved without making the language more complex than it already is. It is extremely difficult to get rid of legacy and backwards compatibility, so the current option of std::array is really what you want. Use it. It's simple. You'll like it. A lot.

C++ function parameters or parameter array

My background and instincts tell me I should always create a tighter and more explicit interface to a function by requiring parameters like this:
bool someFunc(int param1, int param2, char param3, float param4) {
...
}
or requiring an object (struct or class) like:
class someObject {
...
int p1;
int p2;
char c1;
float p4;
}
I have been told by my boss that I should be using something like:
bool someFunc(void *params[], int size) {
...
}
because it creates more extensible (you can iterate over parameters this way) and faster code.
I am only interested in improving my abilities, but my instincts go against this method. Is he right?
Horrible idea. I can't list the reasons why it's bad in a single answer, but the main problem is that it just doesn't work. As a simple example, you can't pass 3, and if you pass 0 it becomes a nullptr. More importantly, you have to cast the values back to a given type anyway, so why not specify the type in the signature?
Now there's a real C++ alternative, variadic templates:
template<typename... Arguments>
void Foo(Arguments... parameters);
In this case, the compiler will know all the types in Arguments..., there's no need to cast anything.
I disagree with the above answer, your instincts are right you should try and create a explicit interface to a function. There are times where you can't have an explicit interface, and then you should consider variadic template arguments, but they're rare. Two Ints a char and float seem like a perfectly reasonable function parameters.
However you're in a very sticky situation, you don't want to go against your boss. I would be skeptical of any programming advice from him, he's either not a very good programmer or worse one of those old school hacky c programmers (see if he uses MACROS everywhere). My advice is to do it his way now, then if you're ever working with that function again later fix it and try and get someone else to review your code.
Your boss is crazy. Such debauchery had some place in C, and even there you would use varargs, not this crazy construct. If you want to program in a dynamically-typed language, either don't use C++, or use arrays of variant types (say boost::variant or QVariant).
The "extensibility" your boss is looking for and obviously missing is otherwise known as function/method overloading. It has its place as a part of a proper design, not as an edict.

Tagged unions (aka variant) in C++ with the same type multiple times

I need to create an union, but 2 members of the union would have the same type, thus I need a way to identify them. For example in OCaml :
type A =
| B of int
| C of float
| D of float
Boost.Variant doesn't seem to support this case, is there a known library which supports that ?
If you want to do this, I think your best option is to wrap the same-but-different-types into a struct which then lets the boost variant visit the proper one:
struct Speed
{
float val_;
};
struct Darkness
{
float val_;
};
You might be able to use BOOST_STRONG_TYPEDEF to do this automatically but I'm not sure it's guaranteed to generate types legal for use in a union (although it would probably be fine in a variant).
You cannot at the moment but C++17's implementation of std::variant fortunately allows it:
A variant is permitted to hold the same type more than once, and to hold differently cv-qualified versions of the same type.
Unlike with the boost version, you can get values by index, something like this (not tested):
// Construct a variant with the second value set.
variant<string, string, string> s(std::in_place_index<1>, "Hello");
// Get the second value.
string first = std::get<1>(s);
Michael Park has written a C++14 implementation of C++17's std::variant.
The c++ code here:
http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/composite_storage/pack/container_one_of_maybe.hpp
is truly a tagged union in that it can contain duplicate types. One nice feature
is the tags can be enumerations; hence, the tags can have meaningful names.
Unfortunately, the compile time cost is pretty bad, I guess, because the implementation
uses recursive inheritance. OTOH, maybe compilers will eventually figure out a way
to lessen the compile time cost.
OTOH, if you want to stick with boost::variant, you could wrap the types,
as Mark B suggested. However, instead of Mark B's descriptive class names,
which require some thought, you could use fusion::pair<mpl::int_<tag>,T_tag>
where T_tag is the tag-th element in the source fusion::vector. IOW:
variant
< fusion::pair<mpl::int_<1>,T1>
, fusion::pair<mpl::int_<2>,T2>
...
, fusion::pair<mpl::int_<n>,Tn>
>
As the fusion docs:
http://www.boost.org/doc/libs/1_55_0/libs/fusion/doc/html/fusion/support/pair.html
say, fusion::pair only allocates space for the 2nd template argument; hence,
this should not take any more room than boost::variant<T1,T2,...,Tn>.
HTH.
-regards,
Larry

Is it possible to achieve temeplatization in C as it is possible in C++

I want to write a function in C that will accept any type of data types like int, char, float, or any other data type and do some operation on them. As this is possible in C++, is it possible in C?
It wouldn't be pretty. Take a look at this page for an example. Lots of macro usage.
About the only thing you can do in C is macros, the poor cousins of templates. For example:
#define max(a, b) ((a) < (b) ? (b) : (a))
Note that this has a huge problem... the macro arguments are evaluated more than once. For example:
max(i+=1, i);
expands to:
((i+=1) < (i) ? (i+=1) : (i));
And the result of that expression could be all kinds of interesting things on various compilers.
So, macros are really a poor substitute for templates. You can make 'functions' that are type agnostic with them. But they come with a number of hurdles and pitfalls that make them practically useless for anything really significant. They are also rather 'hairy' and make your code a lot harder to understand than templates do.
The max example I just gave may not seem that hairy (though the doubled evaluation of arguments is certainly a surprising and difficult to deal with thing), but here is an example of declaring something like a templated vector type with macros, and it is obviously hairy.
You can create and accept a union, or you can take a pointer to the data using the generic void*. C doesn't, however, support templating as in C++.
Yes, it can be achieved by using macros. See
http://www.flipcode.com/archives/Faking_Templates_In_C.shtml
You can arrange a cheat using ... e.g. with varargs function
I guess it must be a void pointer
void *p;
Just typecast and use it. what you have asked is the limitation of c thats why it is introduced in c++
After reading your comment i guess you need an argument to send the datatype of variable
func( void *p, int ) \\ second argument must be a datatype use sizeof to find the datatype

What is std::pair?

What is std::pair for, why would I use it, and what benefits does boost::compressed_pair bring?
compressed_pair uses some template trickery to save space. In C++, an object (small o) can not have the same address as a different object.
So even if you have
struct A { };
A's size will not be 0, because then:
A a1;
A a2;
&a1 == &a2;
would hold, which is not allowed.
But many compilers will do what is called the "empty base class optimization":
struct A { };
struct B { int x; };
struct C : public A { int x; };
Here, it is fine for B and C to have the same size, even if sizeof(A) can't be zero.
So boost::compressed_pair takes advantage of this optimization and will, where possible, inherit from one or the other of the types in the pair if it is empty.
So a std::pair might look like (I've elided a good deal, ctors etc.):
template<typename FirstType, typename SecondType>
struct pair {
FirstType first;
SecondType second;
};
That means if either FirstType or SecondType is A, your pair<A, int> has to be bigger than sizeof(int).
But if you use compressed_pair, its generated code will look akin to:
struct compressed_pair<A,int> : private A {
int second_;
A first() { return *this; }
int second() { return second_; }
};
And compressed_pair<A,int> will only be as big as sizeof(int).
std::pair is a data type for grouping two values together as a single object. std::map uses it for key, value pairs.
While you're learning pair, you might check out tuple. It's like pair but for grouping an arbitrary number of values. tuple is part of TR1 and many compilers already include it with their Standard Library implementations.
Also, checkout Chapter 1, "Tuples," of the book The C++ Standard Library Extensions: A Tutorial and Reference by Pete Becker, ISBN-13: 9780321412997, for a thorough explanation.
You sometimes need to return 2 values from a function, and it's often overkill to go and create a class just for that.
std:pair comes in handy in those cases.
I think boost:compressed_pair is able to optimize away the members of size 0.
Which is mostly useful for heavy template machinery in libraries.
If you do control the types directly, it's irrelevant.
It can sound strange to hear that compressed_pair cares about a couple of bytes. But it can actually be important when one considers where compressed_pair can be used. For example let's consider this code:
boost::function<void(int)> f(boost::bind(&f, _1));
It can suddenly have a big impact to use compressed_pair in cases like above. What could happen if boost::bind stores the function pointer and the place-holder _1 as members in itself or in a std::pair in itself? Well, it could bloat up to sizeof(&f) + sizeof(_1). Assuming a function pointer has 8 bytes (not uncommon especially for member functions) and the placeholder has one byte (see Logan's answer for why), then we could have needed 9 bytes for the bind object. Because of aligning, this could bloat up to 12 bytes on a usual 32bit system.
boost::function encourages its implementations to apply a small object optimization. That means that for small functors, a small buffer directly embedded in the boost::function object is used to store the functor. For larger functors, the heap would have to be used by using operator new to get memory. Around boost version 1.34, it was decided to adopt this optimization, because it was figured one could gain some very great performance benefits.
Now, a reasonable (yet, maybe still quite small) limit for such a small buffer would be 8 bytes. That is, our quite simple bind object would not fit into the small buffer, and would require operator new to be stored. If the bind object above would use a compressed_pair, it can actually reduce its size to 8 bytes (or 4 bytes for non-member function pointer often), because the placeholder is nothing more than an empty object.
So, what may look like just wasting a lot of thought for just only a few bytes actually can have a significant impact on performance.
It's standard class for storing a pair of values. It's returned/used by some standard functions, like std::map::insert.
boost::compressed_pair claims to be more efficient: see here
std::pair comes in handy for a couple of the other container classes in the STL.
For example:
std::map<>
std::multimap<>
Both store std::pairs of keys and values.
When using the map and multimap, you often access the elements using a pointer to a pair.
Additional info: boost::compressed_pair is useful when one of the pair's types is an empty struct. This is often used in template metaprogramming when the pair's types are programmatically inferred from other types. At then end, you usually have some form of "empty struct".
I would prefer std::pair for any "normal" use, unless you are into heavy template metaprogramming.
It's nothing but a structure with two variables under the hood.
I actually dislike using std::pair for function returns. The reader of the code would have to know what .first is and what .second is.
The compromise I use sometimes is to immediately create constant references to .first and .second, while naming the references clearly.
What is std::pair for, why would I use it?
It is just as simple two elements tuple. It was defined in first version of STL in times when compilers were not widely supporting templates and metaprogramming techniques which would be required to implement more sophisticated type of tuple like Boost.Tuple.
It is useful in many situations. std::pair is used in standard associative containers. It can be used as a simple form of range std::pair<iterator, iterator> - so one may define algorithms accepting single object representing range instead of two iterators separately.
(It is a useful alternative in many situations.)
Sometimes there are two pieces of information that you just always pass around together, whether as a parameter, or a return value, or whatever. Sure, you could write your own object, but if it's just two small primitives or similar, sometimes a pair seems just fine.