I'm developing a template function that takes in containers as a parameter. The function will use typeid to check if a container was passed in or not. Since I've never used typeid before, I played around with it but got strange results.
This is my main function:
1 2 3 4 5 6 7 8 9 10 11
int main(){
//Custom class defined in separate file
Vectors::VectorData Testrun = {1,2,3};
int regular;
vector<double> newvector;
cout << typeid(int).name() << endl;
cout << "regular is of type: " << typeid(regular).name() << endl;
cout << "newvector variable is of type: " << typeid(newvector).name() << endl;
cout << "Class type is: " << typeid(Testrun).name() << std::endl;
}
Here is what I get:
i
regular is of type: i
newvector variable is of type: St6vectorIdSaIdEE
Class type is: N7Vectors10VectorDataE
Should this be something to be worried about? Are there any repercussions to be aware of?
Returns a null-terminated character sequence that may identify the type.
The particular representation pointed by the returned value is implementation-defined, and may or may not be different for different types.
Returns an implementation defined null-terminated character string containing the name of the type. No guarantees are given, in particular, the returned string can be identical for several types and change between invocations of the same program.
Also he have used conditional compilation to make sure that code will compile on all compilers (however on compilers different from GCC it will not change anything: you still get type name in whatever format that compiler uses)
The function will use typeid to check if a container was passed in or not
I want to point that your code will not work with user defined containers (If I create class MyCoolStack which satisfies all requirements to containers it will probably be not accepted by your function). In C++14 there will be Constraints which will work with user defined types and can do exactly what you want. (I am not saying that you should drop what you doing now and wait for C++14, just telling you some information)
@JLBorges
Ah okay, thanks. I'm pretty unfamiliar with boost and even more so with cxxabi.h, so this will take some time to understand.
@MiiNiPaa
Thanks for the information. I'll need to practice formulating some designs anyway like playing with JLBorges' sample code, so I'll better understand all of it.
> I'm pretty unfamiliar with boost and even more so with cxxabi.h, so this will take some time to understand.
An understanding of SFINAE is fundamental to understanding C++ templates, and the concept is simple:
if an invalid argument or return type is formed during the instantiation of a function template, the instantiation is removed from the overload resolution set instead of causing a compilation error.
A simple example, using nothing other than standard C++:
#include <iostream>
template < typename T > void foo( T, typename T::const_iterator* = nullptr )
{ std::cout << "(1) this type defines a nested type 'const_iterator'\n" ; }
template < typename T > void foo( T, typename T::first_type* = nullptr )
{ std::cout << "(2) this type defines a nested type 'first_type'\n" ; }
template < typename T > void foo( T, typename T::result_type* = nullptr )
{ std::cout << "(3) this type defines a nested type 'result_type'\n" ; }
#include <vector>
#include <utility>
#include <functional>
int main()
{
std::vector<int> a ;
foo(a) ; // (1) this type defines a nested type 'const_iterator'
// substitution failure for (2) and (3)
std::pair<int,int> b ;
foo(b) ; // (2) this type defines a nested type 'first_type'
// substitution failure for (1) and (3)
std::function< bool(int,int) > c ;
foo(c) ; // (3) this type defines a nested type 'result_type'
// substitution failure for (1) and (2)
}
In the snippet posted earlier, boost spirit was used for convenience. Checking if a type meets the requirement of a container involves many checks (in addition to 'does the type define a 'const_iterator'?); and the library had already implemented those checks.