Generic container & variable element access - c++

In my variable data, when running "add a variable" script code, how to define a generic container for all types? And what is the generic formula to access them? It's annoying because I have to define a vector template for each type (int float double etc). My variable should contain only and only a generic vector object, whatever it's int, or float or double etc. Is it possible? Any idea?

That's the whole point of the Standard Template Library..
std::vector<int>
std::vector<float>
Two vectors - the same class, templated with different types.
If you want a container of differing type you might want to look at std::tuple

If you want a single vector that contains objects of many different types, then you might want to use boost::any, or possibly boost::variant.

Edit:
oh, you want a container that can fit in any type? Yes you can. But within certain restrictions.
See boost::any and boost::variant. boost::variant would enable you to save data of several types enumerated when declaring the boost::variant. boost::any doesn't make you enumerate all types you want to support, but you need to cast them to get back the value yourself.
In short, you must either store the type information somewhere else ( when using boost::any ), or just support a few types (say, a heterogeneous vector that supports int and double using boost::variant)
template in C++ works exactly by eliminating the need to write the same class for every type.
For example:
// function template
template <class T>
T GetMax (T a, T b) {
T result;
result = (a>b)? a : b;
return (result);
}
this GetMax should work for whatever type that has a > operator. So that is exactly what template is for in C++.
If you need more help on implementing a vector on C++ (which, by the way, is not so simple when it comes to custom types that has its own constructor and destructor. You may need allocator to get un-initialized space), read this (Implementation of Vector in C++).

Related

Why can we not access elements of a tuple by index?

tuple <int, string, int> x=make_tuple(1, "anukul", 100);
cout << x[0]; //1
cout << get<0>(x); //2
2 works. 1 does not.
Why is it so?
From Lounge C++ I learnt that it is probably because the compiler does not know what data type is stored at that index.
But it did not make much sense to me as the compiler could just look up the declaration of that tuple and determine the data type or do whatever else is done while accessing other data structures' elements by index.
Because [] is an operator (named operator[]), thus a member function, and is called at run-time.
Whereas getting the tuple item is a template mechanism, it must be resolved at compile time. Which means this can be only done with the <> templating syntax.
To better understand, a tuple may store different types. A template function may return different types depending on the index passed, as this is resolved at compile time.
The operator[] must return a unique type, whatever the value of the passed parameter is. Thus the tuple functionality is not achievable.
get<0>(x) and get<1>(x) are two different functions generated at compile time, and return different types. The compiler generates in fact two functions which will be mangled to something like
int get_tuple_int_string_int_0(x)
and
string get_tuple_int_string_int_1(x)
The other answers here address the issue of why this isn't possible to implement, but it's also worth asking the question of whether it should be possible. (The answer is no.)
The subscript operator [] is semantically supposed to indicate dynamically-resolved access to a element of a collection, such as an array or a list (of any implementation). The access pattern generally implies certain things: the number of elements probably isn't known to the surrounding code, which element is being accessed will probably vary at runtime, and the elements are all of the same observable type (thus, to the calling code, interchangeable).
Thing is, a tuple isn't (that kind of) a collection. It's actually an anonymous struct, and its elements aren't interchangeable slots at all - semantically, they are regular fields. What's probably throwing you off is that they happen to be labelled with numbers, but that's really just an anonymous naming pattern - analogous to accessing the elements as x._0, x._1, etc. (The fact you can compute the field names at compile-time is a coincidental bonus enabled by C++'s type system, and is not fundamentally related to what a tuple is; tuples, and this answer, are not really specific to C++.)
So it doesn't support operator[] for the same reason that plain old structs don't support operator[]: there's no semantically-valid use for it in this context. Structures have a fixed set of fields that aren't interchangeable or dynamically computable, and since the tuple is a structure, not a collection, it follows the same rule. Its field names just look different.
It can be supported, it just needs to take a compile-time index. Since parameters of a function cannot be made constexpr, we need to wrap the index within a type and pass that instead. (e.g. std::integral_constant<std::size_t, N>.
The following is an extension of std::tuple that supports operator[].
template <typename... Ts>
class tuple : public std::tuple<Ts...> {
public:
using std::tuple<Ts...>::tuple;
template <std::size_t N>
decltype(auto) operator[](std::integral_constant<std::size_t, N>) {
return std::get<N>(*this);
}
};
It would be used like so:
tuple<int, std::string> x(42, "hello");
std::cout << x[std::integral_constant<std::size_t, 0>{}] << std::endl;
// prints: 42
To mitigate the std::integral_constant crazy, we can use variable template:
template <std::size_t N>
std::integral_constant<std::size_t, N> ic;
With this, we can say:
std::cout << x[ic<1>] << std::endl; // prints: hello
So it could be done. One guess as to why this is currently not available is because features such as std::integral_constant and variable templates may not have existed at the time std::tuple was introduced. As to why it doesn't exist even though those features exist, I would guess it's because no one have yet to proposed it.
It's not very clean supporting operator[] given you can't vary the static return type to match the accessed element. If the Standard Library had incorporated something like boost::any or boost::variant, it would make more sense.
Put another way, if you write something like:
int n = atoi(argv[1]);
int x = x[n];
Then what should it do if n doesn't address an int member of the tuple? To even support checking you'd need to store some manner of RunTime Type Information for tuples, which is extra overhead in the executable/memory.
Containers that support the subscript operator (i.e., operator[]) like std::vector or std::array are collections of homogenous values. Whatever the index provided to the subscript operator is, the value to return is always of the same type. Therefore, those containers can define a member function with the following declaration:
T& operator[](int);
Where T is the type of every element in the collection.
On the other hand, an std::tupe is a collection of heterogeneous values. The return value of a hypothetical subscript operator for std::tuple needs to vary with the index. Therefore, its return type depends on the index.
In the declaration of the operator[] given above, the index is provided as a function argument and therefore may be determined at run time. However, the return type of the function is something that needs to be determined at compile time, not at run time.
Since the return type of such a function depends on the index but must be determined at compile-time, the solution is to define instead a function template that accepts the index as a (non-type) template parameter. This way, the index is provided as a compile-time constant and the return type is able to change with the index:
template<std::size_t I, class... Types>
typename std::tuple_element<I, tuple<Types...>>::type& get(tuple<Types...>&) noexcept;
As you can see, std::get's return type depends on the index, I:
std::tuple_element<I, tuple<Types...>>::type&
Because tuple has no operator "bracket".
Why is it so? You cannot resolve templates based only on the return value. You cannot write
template<typename T>
T tuple::operator [](size_t i) const ;
Which is absolutely necessary to be able to allow statements like x[0]

Equivalent of std::pair in C

What is the C equivalent of std::pair from C++? I'm trying to find the equivalent on the web and can't find anything but explanations of what it does.
There isn't one. std::pair is a template, and C doesn't have anything similar to templates.
For a given specialisation of the template, you can define a structure that's more or less equivalent; so that std::pair<int, double> is similar to
struct pair_int_double {
int first;
double second;
};
but you've chosen the wrong language if you want a generic template.
While the other answers are correct in saying that C does not have templates, the assumption that you can not have a generic pair type is wrong. If you really need a generic type, that is, you don't want to manually define a struct for each pair of types you want to use a pair for, you are left with 3 options.
Firstly, you could use a struct containing two void* types, and use these pointers as generic storage pointers for you data. (This is needlessly complicated and I would not generally recommend it)
Secondly, if the amount of types for your pair structure is known beforehand, you could use a union in your struct, for example
struct pair
{
union
{
int first_int;
float first_float;
};
union
{
int second_int;
float second_float;
}
}
Or thirdly, you could use parametric macros to generate struct definitions of types you need, without constantly repeating yourself.
Or, alternatively think of a way to write your code that does not rely on templated types.
std::pair in C++:
template <class t1, class t2>
struct pair {
t1 first;
t2 second;
}
std::pair takes advantage of templates, so each concrete instantiation defines a new class std::pair<myT1, myT2>.
There's no such thing in C, you may have to declare a different struct each time, or use void *...
struct pair {
struct myT1 first;
struct myT2 second;
}
As other answers made clear, C doesn't have anything similar to C++ templates.
However, you may use void* as a way to store addresses of variables of any type, by casting to a pointer of the data type you want.
Following this, a possible implementation of a pair structure in C would be as follows:
struct pair {
void* first;
void* second;
};

Vector of typedefs

Is it possible in ANY way to have a vector of type(def)s in C++11/14 ?
The first thing I tried was have a vector of a base class and somehow get the typedef from it's derived form but I can't get this to work whatever I try (not possible most likely).
Pseudo-C++:
class base
{
/* somehow access 'type' from derived */
}
template <typename T>
class derived : base
{
typedef T type;
}
vector<base*> vec;
vec.push_back( new derived<int> );
vec.push_back( new derived<double> );
vec.push_back( new derived<float> );
vec.push_back( new derived<string> );
for(auto& item : vec)
static_cast< item->type >( /* something */ );
Boost MPL provides a compile time construct for this, for example:
typedef boost::mpl::vector<int, double, std::string, CustomA, CustomB> seq_of_types;
You can interact with this at compile type using the extensive set of meta functions defined in mpl. There are also some run-time crossover functions too. The important point here is that this is a sequence of types, there are no instances of each type to interact with. Even the runtime functions only allow interacting with types.
Boost Fusion (and std::tuple) steps in here to provide a runtime heterogenous container, so for example
boost::fusion::vector<int, double, std::string> v{10, 100., "Foo"};
Now at compile time, you have access to the type information of each entry, and at runtime you have an instance of each type in the sequence to work with.
It could be possible that what you are trying to achieve could be done with plain inheritance without having to resort to the above, so the vector holds a pointer to base class, which has a virtual function which is overriden in the derived classes which does what you want. This is possibly the cleanest.
Alternatively, the same is possible, without resorting to using inheritance if you use a variadic type such as boost::variant, for example:
std::vector<boost::variant<int, double, std::string>> entries;
Now each entry is one of the types of int, double, std::string. Then as you iterate, you can use a static visitor to operate on the specific instance. I think I've answered a question on SO a while ago which demonstrates this.
So which will it be?
EDIT: base on your last comment, then the latter (variant) doesn't really fly, and nor does plain inheritance. I think a fusion vector is really not necessary either as you don't need an instance of each type. The most suitable thing for you then is the mpl::vector, and use the runtime function mpl::for_each
Maybe you could look into Loki's type lists (see here). There's a question on to use them here. I think this is as close as it gets to what you're looking for. Boost MPL also has something like that (see this question), with type lists and type vectors.
No, you can't. Types in C++ aren't objects, and they can't be used as values.
Depending what you actually need, you might be able to do something with type_info (or rather, pointers to them). This is not the type, and it can't be used to access the type, but it can be used for example in equality comparisons to determine whether two type_info objects refer to the same or different types.
Depends on what you mean by "vector"
A specialization of std::tuple is a (compile-time) ordered collection of types.
You can index them (untested code):
typedef std::tuple<int, long, void, std::string, std::complex<float> Tuple;
typename std::tuple_element<1, Tuple>::type foo; // foo is of type long
You can do all sorts of manipulations (at compile-time) on tuples, and the results of these manipulations are types (or other tuples). C++14 formalizes (but did not invent) the idea of "index sequences", which let you do pretty much arbitrary tuple-type -> tuple-type transforms.

Constant-sized vector class?

Is there a C++ standard type for holding a vector having a constant size? For example, something like a tuple with all element types being the same, so I only have to provide the size as a template argument?
I would like to have the same/similar behavior as when using std::vector, but the type should be as compact and efficient as a raw array (so no dynamic allocation, no run-time size information, etc.)
I prefer a C++03-compatible solution, so reusing a std::tuple isn't what I want.
Does the following class do what I want?
template<typename T, int N>
struct vec
{
T component[N];
// (+ some logic and accessors like operator[]...)
};
// concrete example:
vec<int,3> myVector;
Does it really differ from just saying T myVector[N] (concrete example int myVector[3])? Because that's what I am currently doing but I'm experiencing a couple of problems, since raw arrays are "just pointers" (+ size information) and can't be used as return values as well as aren't really passed by value (no deep copy occures).
C++11 has std::array; which is basically the same as you wrote.
For C++03, use boost::array which is basically compatible to std::array.

How to create type-safe int - enum in C++?

I need to create many classes that are somewhere between integer and enum.
I.e. have the arithmetics of integer but also are not implicitly converted to int.
Have a look at the answer to this question - BOOST_STRONG_TYPEDEF did exactly what I wanted.
// macro used to implement a strong typedef. strong typedef
// guarentees that two types are distinguised even though the
// share the same underlying implementation. typedef does not create
// a new type. BOOST_STRONG_TYPEDEF(T, D) creates a new type named D
// that operates as a type T.
One possibility is to create a class with the "enums" defined as invariant members of the class with a ::GetValue() method and the mathematical operations you need to use overloaded to use GetValue() to do the math in question.