Template type in std::map - c++11

I want to create a vector of pairs. One of the pair members will be std::string and the second one templated type.
However this is giving me compilation error:
template <class T>
std::vector<std::pair<std::string, T> > arrayMembers;
Is this even possible? If som, how can I make it work?
Thanks and Regards

You can declare a template alias like so:
template<typename T>
using arrayMembers = std::vector<std::pair<std::string, T>>;
Then you declare your actual variable like you would, for example, for a std::vector, like so:
arrayMembers<MyType> table;

Related

In C++ can you capture a packed parameter with a using statement

In a templated class, I would like to make an alias of a variadic parameter, something like:
template<typename ... TYPES>
class X
{
using Types = TYPES;
};
It is easy to make a std::tuple of it, but is there a syntax for doing the above.
The reason is I would like to reference this from the templated class in another class.

C++ - no match for ‘operator<’

I have the following map:
std::map<my_msgs::Nodelet, int> mRunningProcPID;
When trying to insert a new pair to the map I am getting the following error:
error: no match for ‘operator<’ (operand types are ‘const my_msgs::Nodelet_<std::allocator<void> >’ and ‘const my_msgs::Nodelet_<std::allocator<void> >’)
{ return __x < __y; }
I get it that I need to override the < operator for my_msgs::Nodelet, the problem is that I do not have access to that h file since it is being auto generated by ROS.
Any idea what can I do?
The problem is that std::map will attempt to index the mapped elements, and it doesn't know how to index my_msgs::Nodelet because it doesn't know how to compare this object.
You have to provide a third parameter when declaring this map, with a Compare function, or implement the necessary interface (handler for operator <) for it to use the default comparison method.
But you can also avoid this trouble by just using std::unordered_map instead.
std::unordered_map will do pretty much the same thing std::map does but it doesn't bother to index the elements. This approach is also considered faster in many cases.
Any idea what can I do?
Option 1: Use a non-member function to compare two Nodelet objects.
You can define a non-member function operator< between two Nodelet objects with the following signature.
bool operator<(my_msgs::Nodelet const& lhs, my_msgs::Nodelet const& rhs);
You don't need the ability to modify the class to do that. You can declare it in your own .h file and define it in your own .cpp file.
Option 2: Use a functor to compare two Nodelet objects
You can define a functor with the following interface:
struct CompareNodelet
{
bool operator()(my_msgs::Nodelet const& lhs, my_msgs::Nodelet const& rhs) const;
};
and use it to construct the map.
std::map<my_msgs::Nodelet, int, CompareNodelet> mRunningProcPID;

Template template in c++11 error

I've been reading the chapter 5 of "C++ Templates, The complete guide", and i've seen the concept of "template template" templates, so tried myself.
In a template class, i've declared my template like this:
template <typename TipoClave, typename TipoDato,
template <class Elem, class Alloc = allocator<Elem>> class Lista = vector>
And this works. My problem comes when I try to use a different container than the default.
My class is as follows:
class Tabla
{
public:
struct Celda {
TipoClave clave;
TipoDato dato;
};
Tabla(unsigned tam)
{
t.resize(tam);
}
///< Some other functions
private:
typedef Lista<Celda> ListaDatos;
Lista<ListaDatos> t;
};
And then, when I try to use it from the main program like this:
int main (void)
{
Tabla<string,Alumno,array> tabla(200);
///< Some stuff
return 0;
}
But this line Tabla<string,Alumno,array> tabla(200); does not compile, getting me an error like:
test_tabla_t.cpp: In function ‘int main()’: test_tabla_t.cpp:20:27:
error: type/value mismatch at argument 3 in template parameter list
for ‘template class Lista> class Tabla’ Tabla
tabla(200);
I've tried to use Tabla<string,Alumno,vector> tabla(200);, and it works, so I don't know how to solve this error.
Assuming you're trying to use std::array, it does not take an Allocator template parameter. Its second argument is the size of the array.
template<
class T,
std::size_t N
> struct array;
You haven't mentioned how experienced you are with C++, but since you're trying to learn more, I'll say that I've been using C++ for nearly a decade and can count on one hand the number of times I've used template template parameters.
In this case, you want Lista to be "something that acts like a sequence container[1]", you might like to read about concepts[2], which may make it into C++20. They allow you to tell the compiler the interface you want a template parameter to have.
In the meantime, it might be easier to declare Lista as a plain template parameter.
[1] http://en.cppreference.com/w/cpp/concept/SequenceContainer
[2] https://en.wikipedia.org/wiki/Concepts_(C%2B%2B)

std forward implementation and reference collapsing

in scott meyers book he mentioned an implementation for std forward that goes like this (non std conformant)
template <typename T>
T&& forward(typename remove_reference<T>::type& param)
{
return static_cast<T&&>(param);
}
The question is why do we need to remove reference here?
so a typical forward usage would be in a universal reference function as follows:
template <typename T>
void f(T&& fparam)
{
g(forward<T>(fparam)); // assume there is g function.
}
without remove reference, the forward would look like this
template <typename T>
T&& forward(T& param);
now the two cases are:
fparam is rvalue in that case inside f function the T is deduced as
non reference object type so the forward call take the param by
lvalue reference and cast it to T&& (because T is non reference).
fparam is lvalue then inside f the T is deduced as T& then forward
will take (as argument) a reference to an lvalue reference (collapsing to lvalue
reference) then the static cast would be T& && which is again lvalue
reference.
so why do we need to remove reference from param of forward? does it have to do with disallowing deducing types maybe? can somebody maybe give a detailed explanation.
The question that is referenced as duplicate is not, the answer basically says that the std library uses remove reference but why?
Does it have to do with disallowing deducing types maybe?
Yes, typename std::remove_reference<T>::type introduces a non-deduced context. It prevents the user from mistakenly writing...
std::forward(something)
...and forces him/her to provide an explicit template argument:
std::forward<T>(something)

Convert Boost::Map iterator to std::iterator

I was writing wrapper methods for Boost unordered map container. In boost Unordered Map there is a method begin() which returns an iterator to the first element.Actually in my wrapper class i want to return a std::Unordered_map::iterator instead of boost::unordered_map::iterator from my Begin method.
Example code:
template
boost::unordered_map<key, value> m_myMap;
boost::unordered::unordered_map::iterator MyWrapper<>::Begin()
{
return m_myMap.begin();
}
In the above code i want to return std::Unordered_map::iterator
Please help
You can't. C++ is a strongly typed language.
The best you can do is
use std::unordered_map
Use type erasure to hide the implementation (boost::any_iterator or boost::any_range)
My spidy sense tells me that you should take the iterators by deduced template argument type, instead of hard-coding them into your algorithms.
template <typename Iterator>
void foo_algo(Iterator begin, Iterator end, int some_data) {
...

Resources