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;
};
Related
I'm attempting to create a simple stack using templates that accepts both values and types as the payload:
// type that marks end of stack
struct StackEmptyNode {};
//
template<auto Value, typename T = StackEmptyNode>
struct StackNode {};
The use of auto Value allows me to declare stacks with values such as StackNode<3, StackNode<4, StackNode<9>>>;
However I also want to the same stack to accept types as the payload. This can be done by changing auto Value to template Value which allows me to declare StackNode<int, StackNode<float, StackNode<std::string>>>;.
I want to be able to use either for the same StackNode implementation. Is this possible using templates?
I want to be able to use either for the same StackNode implementation. Is this possible using templates?
Short answer: no.
Long answer.
The best I can imagine is to use types and wrap values inside types, using (by example) the standard std::integral_constant class.
So you can write something as
StackNode<int, StackNode<std::integral_constant<int, 4>, StackNode<std::string>>>;
//.......................^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the value 4 become a class
Using the new (C++17) auto value facility, you can simplify a little writing a simple value wrapper
template<auto>
value_wrapper
{ };
so you can avoid the type of the value
StackNode<int, StackNode<value_wrapper<4>, StackNode<std::string>>>;
// ......................^^^^^^^^^^^^^^^^ now 4 is simply 4, without it's type
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.
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++).
I am writing a COM wrapper for a COM object that sends different types of values from a client and want to map these types in a Map to their actual C++ type, such as VT_BSTR to a wstring, etc.
I was thinking of defining an enumuration of all COM Variant types and then using a map to have that Enum as the key and the actual type containing the retrieved value, however I'm running into the issue that I cannot seem to find a global type to put in my map that I can cast to a string or double or whatever is handed to me to place in the map.
Perhaps my thinking of how to do this is entirely wrong, please advice?
I was thinking of a void pointer, however it seems the compiler doesn't like my casts:
(example)
enum Type
{
VT_INTEGER=0,
VT_DBL=1
};
map<Type, void*> typemap;
typedef pair<Type, void*> m_typepair;
typemap.insert( m_typepair(VT_INTEGER, 0));
typemap.insert( m_typepair(VT_DBL, (double)2.5)); // it does not like this cast
map<Type, void*>::iterator m_typeiter;
Iterating this map would probably need a switch statement inside to find the right type, I'm not sure if there is a better way?
Not sure what you're trying to do, it certainly sounds wrong. A VARIANT you get from a client needs to be converted to the type that you know how to deal with. That's easy to do, just call the VariantToXxxx() function. For example, use VariantToString() if you want to get a string.
There are several C++ wrapper classes already available that make this easier. _variant_t, CComVariant, COleVariant. They all do the same thing, just different #include files. _variant_t is a good one because it doesn't tie you into either MFC or ATL. Unless you are already using them. Their ChangeType() method makes the conversion. Memory management is automatic.
I usually use template specialization for this kind of tasks. I have a template function that converts from a variant type to a C++ type that looks like this:
template <typename T>
T variantToCpp(const Variant&);
template <>
int variantToCpp<int>(const Variant& v)
{
// Check that v really contains an int, if not, you can silently fail or throw an exception
// Get and return the int
}
template <>
std::wstring variantToCpp<std::wstring>(const Variant& v)
{
// Check that v really contains a string, if not, you can silently fail or throw an exception
// Get and return the string
}
// etc. for each C++ type
// Usage
int i = variantToCpp<int>(someVariantIGotViaCOM);
This way you get a constant-time conversion from a Variant to a C++ type. Also note that the default templated function has no body - it will cause a linker error (on most compilers) if someone tries to use a conversion for an unspecialized type.
Similarly you can do the conversion from a C++ type to a Variant:
template <typename T>
Variant cppToVariant(T);
template <>
Variant cppToVariant<int>(int val)
{
// Convert to variant and return it
}
// etc. for each type
// Usage:
int i = 10;
Variant var = cppToVariant(i); // You don't even need to explicitly specify the type here, the compiler deduces it
If you insist on using a map and tons of ifs for this kind of conversion, you can use your void* pointer, you just have to initialize it with a pointer to the type:
int *myInteger = new int; *myInteger = 42;
double *myDouble = new double; *myDouble = 42;
typemap.insert( m_typepair(VT_INTEGER, myInteger));
typemap.insert( m_typepair(VT_DBL, myDouble));
// Don't forget to free them when you clear the map
If you aren't satisfied with any of the above solutions, boost::any might be worth looking at.
Are you aware of _variant_t ? You might be reinventing the wheel. It has all the relevant constrcutors and overloaded assignment. I.e. _variant_t var = 0.0 works as expected (VT_R8)
how can i get the type of the elements that are held by a STL container?
container::value_type
For containers in general it will be X::value_type. For associative containers it will be X::mapped_type (X::value_type corresponds to pair<const Key,T>). It is according to Chapter 23 of C++ Standard.
To check that types are equal you could use boost::is_same. And since C++11 — std::is_same.
Checking whether two types are the same can be achieved like this (without RTTI, value is usable at compile-time):
template <class T, class U>
struct same_type
{
static const bool value = false;
};
//specialization for types that are the same
template <class T>
struct same_type<T, T>
{
static const bool value = true;
};
//sample usage:
template <class FirstContainer, class SecondContainer>
bool containers_of_same_type(const FirstContainer&, const SecondContainer&)
{
return same_type<
typename FirstContainer::value_type,
typename SecondContainer::value_type
>::value;
}
#include <vector>
#include <list>
#include <iostream>
int main()
{
std::cout << containers_of_same_type(std::vector<int>(), std::list<int>());
std::cout << containers_of_same_type(std::vector<char>(), std::list<int>());
}
(This is basically how boost::is_same works, minus workarounds for certain compilers.)
In what sense?
Maybe using RTTI and typeid()?
Probably you have to use container::valuetype where container is the name of your container (for example std::vector)
Alek
Use something like this:
if (typeid(yourVariable)==typeid(YourClass)) //...
Alek
You need to give us more context. If you mean you want the value known at compiletime so it's easy to change it then use container::value_type.
typedef vector<int> coordinates;
coordinates seq;
fib::value_type elem = seq.back(); // it's easy to change int type
If what you mean is that the container may hold various concrete (derived) types and you wish to know them at runtime then you should probably re-evaluate your approach. In object-oriented programming hiding the type at runtime is sometimes a powerful approach, because it means you make fewer assumptions about what you're working with. You can of course use RTTI, but there's probably a better way: we'd need more context to tell.
If you wish to compare types then you're probably heading the runtime path. C++ supports polymorphism, which is essentially that type-comparison you're looking after -- but built into the language. You want to execute a different set of instructions based on the type? Polymorphism allows you to execute a different function based on the type of the object. You need not write a single extra line of code -- only derive from a common base.
given the types are known statically you can check they are the same statically without using rtti by using template specialization. e.g. use something like http://www.boost.org/doc/libs/1_40_0/libs/type_traits/doc/html/boost_typetraits/reference/is_same.html or if boost isn't available roll your own