C++ variadic template - c++

I am trying to create a polymorhic container working with variadic templates.
Container is initialized as
container<tag, std::string, int, int, int> m;
I want to use following syntax:
auto& v2 = m.find<2, 3, 4>(255, 0, 0);
Template arguments would specify "columns" and for parameters, I want appropriate type to be expected by compiler.
For one template argument (find<2>(255)) I used:
template < int idx > const typename value_type &
find( const typename std::tuple_element<idx, typename value_type>::type &key) {
const std::size_t row_id = getId<idx>(key);
return data_.at(row_id);
}
That worked perfectly, so I wanted to expand it as follows:
template<int ... idx> const typename value_type &
find(const typename std::tuple_element<idx..., typename value_type>::type &keys...) {
const std::size_t row_id = getId<idx...>(keys);
return data_.at(row_id);
}
What's not working at all. Compilation error C2660 - find: function does not take 3 arguments. Can someone explain me, what am I missing here?
Thanks.
EDIT:
Header of container class is
template<typename ... Arguments> class container
value_typementioned is
typedef std::tuple < Arguments... > value_type;
EDIT2:
T.C.'s answer was indeed useful, though I'm still crawling through my bugs with variadic templates. Currently:
enum tag {/*...*/}
int main() {
container<tag, std::string, int, int, int> m;
}
template<typename ... Arguments> class container {
public:
typedef std::tuple < Arguments... > value_type;
std::vector<value_type> data_;
template <int id> void narrowRange(
std::set<std::size_t> & range,
const typename std::tuple_element<id, typename value_type>::type &key)
{
// all commented out
}
template <int id, int ... idx>
void narrowRange(
std::set<std::size_t> & range,
const typename std::tuple_element<id, typename value_type>::type & key,
const typename std::tuple_element<idx, typename value_type>::type & ... keys) // <-
{
narrowRange<idx...>(range, keys...);
// rest commented out
}
Will invoke internal error in MSVS2013 on the marked line. Any suggestions why would be appreciated.

First, value_type doesn't need typename - I'm fairly sure the grammar actually bans it.
Second, you are expanding idx too early, and also incorrectly attempting to expand keys in the declaration. (That second ... is actually being parsed as a C-style varargs.) You are also not expanding the pack keys in the function body. Assuming that you want find<2, 3, 4>(255, 0, 0) to call getId<2, 3, 4>(255, 0, 0), the correct syntax is
template<int ... idx> const value_type &
find(const typename std::tuple_element<idx, value_type>::type &... keys) {
const std::size_t row_id = getId<idx...>(keys...);
return data_.at(row_id);
}

Related

Variadic template parameter inference with nested maps

Working in C++, there's some times I'm working with nested maps. For instance, hypothetically:
enum Color { RED, GREEN, BLUE};
enum Shape { CIRCLE, SQUARE, TRIANGLE };
std::unordered_map<Color, std::unordered_map<Shape, int>> shapeColorCount;
For these situations, it would be useful to use variadic templates to write setter and getter functions that are templated over the types of the keys. The goal would be something like:
template<typename TValue, typename TKeys...>
TValue& nestedGet(MapTypeHere t_map, const TKeys&... t_keys);
void nestedSet(MapTypeHere t_map, const TValue& t_value, const TKeys&... t_keys);
It's not too hard to define these functions recursively, but my main problem is getting the type inference for the template parameters to work correctly. The problem is specifying MapTypeHere. I can almost write something like
template<typename TValue, typename TKey>
using Map = std::unordered_map<TKey, TValue>;
template<typename TValue, typename TOuterKey, typename... TInnerKeys>
using Map = std::unordered_map<TOuterKey, Map<TValue, TInnerKeys...>;
template<typename TValue, typename... TKeys>
TValue& nestedGet(Map<TValue, TKeys...>& t_map, const TKeys&... t_keys);
void nestedSet(Map<TValue, TKeys...>& t_map, const TValue& t_value, const TKeys&... t_keys);
Trying to create a recursive using directive, but it complains that I'm trying to use a parameter pack in a non-pack template variable when it attempts to use the base case for Map. If I wrap them in structs, it seems to allow it to do this recursive using declaration, but then I have a problem where the type inference doesn't work. Going back to the above example:
std::unordered_map<Color, std::unordered_map<Shape, int>> shapeColorCount
nestedSet<int, Color, Shape>(shapeColorCount, 5, Color::RED, Shape::SQUARE); // This works
nestedSet(shapeColorCount, 5, Color::RED, Shape::SQUARE); // It can't figure out the types for the template
Is there a way to get this setup working correctly?
Yes, you can write the following functions:
template<typename Map, typename Value, typename FirstKey, typename ...RestKeys>
void nestedSet(Map& map, Value const& value, FirstKey const& key, RestKeys const&... rest_keys)
{
if constexpr(sizeof...(RestKeys) == 0)
map[key] = value;
else
nestedSet(map[key], value, rest_keys...);
}
template<typename Map, typename FirstKey, typename ...RestKeys>
auto& nestedGet(Map& map, FirstKey const& key, RestKeys const&... rest_keys)
{
if constexpr(sizeof...(RestKeys) == 0)
return map[key];
else
return nestedGet(map[key], rest_keys...);
}
Note that this solution doesn't depend on a particular unordered_map<Color, std::unordered_map<Shape, int>> instantiation. It works for any instantiations of key and value types, and for any depth of nested unordered_maps.
Here's a demo.
Also, if you don't have c++17, then you can rewrite the if constexpr solution with an overloaded template that takes a single KeyType parameter.
Is too late to play?
It seems to me that, given a recursive nestedGet(), that you can write using if constexpr (if you can use C++17) or also using overloading as follows,
template <typename M, typename K>
auto & nestedGet (M & map, K const & key)
{ return map[key]; }
template <typename M, typename K, typename ... RKs>
auto & nestedGet (M & map, K const & key, RKs const & ... rks)
{ return nestedGet(map[key], rks...); }
the nestedSet() function can be written upon nestedGet() simply as follows
template <typename M, typename V, typename ... Ks>
void nestedSet (M & map, V const & value, Ks const & ... keys)
{ nestedGet(map, keys...) = value; }
The following is a full compiling example
#include <iostream>
#include <unordered_map>
enum Color { RED, GREEN, BLUE};
enum Shape { CIRCLE, SQUARE, TRIANGLE };
template <typename M, typename K>
auto & nestedGet (M & map, K const & key)
{ return map[key]; }
template <typename M, typename K, typename ... RKs>
auto & nestedGet (M & map, K const & key, RKs const & ... rks)
{ return nestedGet(map[key], rks...); }
template <typename M, typename V, typename ... Ks>
void nestedSet (M & map, V const & value, Ks const & ... keys)
{ nestedGet(map, keys...) = value; }
int main ()
{
std::unordered_map<Color, std::unordered_map<Shape, int>> shapeColorCount;
nestedSet(shapeColorCount, 42, Color::RED, Shape::SQUARE);
std::cout << nestedGet(shapeColorCount, Color::RED, Shape::SQUARE) << std::endl;
}

C++ why does SFINAE fail with only a class template parameter?

I'm using SFINAE in the style of this answer in order to call a generic vector object by using an appropriate member function. For example, the following code calls operator[](int) const first, and if that doesn't exist then operator()(int) const:
template<int I> struct rank : rank<I-1> { static_assert(I > 0, ""); };
template<> struct rank<0> {};
template<typename VectorType>
struct VectorWrapper
{
auto get(int i) const
{
return get(v, i, rank<5>());
}
template<typename V, typename = std::enable_if_t<has_bracket_operator<const V>::value> >
auto get(V const& v, int i, rank<2>) const
{
return v[i];
}
template<typename V, typename = std::enable_if_t<has_parenthesis_operator<const V>::value> >
auto get(V const& v, int i, rank<1>) const
{
return v(i);
}
VectorType v;
};
With the has_bracket_operator and has_parenthesis_operator traits set up as suggested in this thread, the whole compiles and seems to work.
However, passing the member vector to the overloaded class templates seems unnecessary from the first, so I tried to set up the same without passing it. For this, I replaced the template parameter V with the VectorType parameter used to set up the class template:
template<typename = std::enable_if_t<has_bracket_operator<VectorType>::value> >
auto get(int i, rank<2>) const
{
return v[i];
}
template<typename = std::enable_if_t<has_parenthesis_operator<VectorType>::value> >
auto get(int i, rank<1>) const
{
return v(i);
}
Now, however, the compilation fails (in gcc 5.1.0) with the following error message:
/usr/local/include/c++/5.1.0/type_traits: In substitution of 'template<bool _Cond, class _Tp> using enable_if_t = typename std::enable_if::type [with bool _Cond = has_parenthesis_operator<std::vector<int> >::value; _Tp = void]':
main.cpp:46:10: required from 'struct VectorWrapper<std::vector<int> >'
main.cpp:59:38: required from here
/usr/local/include/c++/5.1.0/type_traits:2388:61: error: no type named 'type' in 'struct std::enable_if<false, void>'
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
DEMO
Questions:
What is the reason for this compilation error?
Is there an appropriate workaround other than that of my first code block? (That is, one that retains the usual coding style -- where one does not have to pass members).
SFINAE comes to us from [temp.deduct]/8, emphasis mine:
If a substitution results in an invalid type or expression, type deduction fails. An invalid type or expression is
one that would be ill-formed, with a diagnostic required, if written using the substituted arguments. [ Note:
If no diagnostic is required, the program is still ill-formed. Access checking is done as part of the substitution
process. —end note ] Only invalid types and expressions in the immediate context of the function type and
its template parameter types can result in a deduction failure.
The immediate context is what's in the template declaration. In your initial example:
template<typename V, typename = std::enable_if_t<has_bracket_operator<const V>::value> >
auto get(V const& v, int i, rank<2>) const
V is in the immediate context, so a substitution failure on the enable_if is just a deduction failure.
However, in your second example:
template<typename = std::enable_if_t<has_bracket_operator<VectorType>::value> >
auto get(int i, rank<2>) const
VectorType is not in the immediate context of get, so a failure here would not be a deduction failure, it would be a hard error.
Unless VectorType happens to have all of these operators.
The solution to any template problem is to just add more template. In this case, force VectorType to be in the immediate context by introducing another type:
template<typename T=VectorType, typename = std::enable_if_t<has_bracket_operator<T>::value> >
auto get(int i, rank<2>) const
And call get<>().
In your failing example, the template parameter VectorType has already been determined by the time get is being resolved. To make SFINAE work, you need to make the template parameters you are using for SFINAE resolve at that method call. The following is a modification of your first example to work like you want to:
template<int I> struct rank : rank<I-1> { static_assert(I > 0, ""); };
template<> struct rank<0> {};
template<typename VectorType>
struct VectorWrapper
{
auto get(int i) const
{
return get(v, i, rank<5>());
}
template<typename V=VectorType, typename = std::enable_if_t<has_bracket_operator<const V>::value> >
auto get(int i, rank<2>) const
{
return v[i];
}
template<typename V=VectorType, typename = std::enable_if_t<has_parenthesis_operator<const V>::value> >
auto get(int i, rank<1>) const
{
return v(i);
}
VectorType v;
};
This way, V is resolved when get is called, and it will correctly use SFINAE.
Or you can just use tag-dispatching:
auto get(int i) const
{
return get(i, has_bracket_operator<VectorType>(), has_parenthesis_operator<VectorType>());
}
auto get(int i, std::true_type /*brackets*/, std::false_type /*parenthesis*/) const
{
return v[i];
}
auto get(int i, std::false_type /*brackets*/, std::true_type /*parenthesis*/) const
{
return v(i);
}
demo

Should std::hash<T> work when T is std::pair<two simpler types also supported by std::hash>?

I was using an ordered set declared as so:
std::set<std::pair<const std::string, const myClass *> > myset;
After doing some analysis of the way I was using the set, I concluded that an unordered_set would be a smarter choice. But when I changed std::set to std::unordered_set, I got a vast spew of error messages from my compiler (g++ 4.8.1) complaining of an
invalid use of incomplete type struct std::hash<std::pair<const std::basic_string<char>, const myClass * > >
I figured out that std::hash didn't know how to deal with a type which was std::pair, despite the fact that the two types that made up the pair were each hashable. I think error for hash function of pair of ints contains relevant information about the C++11 standard that explains why things went awry. (There's no good explanation for the impenetrable wall of error text that g++ emits for this.)
It would seem to me that
std::hash<std::pair<T1, T2>> hasher(make_pair(x,y))
= some_func(std::hash<T1>hasher(x), std::hash<T2>hasher(y) )
where some_func() could be as simple as XOR (or not; see Why is XOR the default way to combine hashes?)
Is there a good reason for the standard to not require std::hash to know how to construct a hash value for an object which is a pair of types that are each hashable?
The reason is simple, it was not added to the standard. The same is true of hashing other structures like tuple.
Things tend to be added to the standard when they are good enough, not when they are perfect, as perfection is the enemy of the good. More specializations of std::hash are not things that will break code (that often), so adding new ones is relatively harmless.
In any case, to that end, we can write our own hash extenders. As an example:
namespace hashers {
constexpr size_t hash_combine( size_t, size_t ); // steal from boost, or write your own
constexpr size_t hash_combine( size_t a ) { return a; }
constexpr size_t hash_combine() { return 0; }
template<class...Sizes>
constexpr size_t hash_combine( size_t a, size_t b, Sizes... sizes ) {
return hash_combine( hash_combine(a,b), sizes... );
}
template<class T=void> struct hash;
template<class A, class B>
constexpr size_t custom_hash( std::pair<A,B> const& p ) {
return hash_combine( hash<size_t>{}(2), hash<std::decay_t<A>>{}(p.first), hash<std::decay_t<B>>{}(p.second) );
}
template<class...Ts, size_t...Is>
constexpr size_t custom_hash( std::index_sequence<Is...>, std::tuple<Ts...> const& p ) {
return hash_combine( hash<size_t>{}(sizeof...(Ts)), hash<std::decay_t<Ts>>{}(std::get<Is>(p))... );
}
template<class...Ts>
constexpr size_t custom_hash( std::tuple<Ts...> const& p ) {
return custom_hash( std::index_sequence_for<Ts...>{}, p );
}
template<class T0, class C>
constexpr size_t custom_hash_container( size_t n, C const& c) {
size_t retval = hash<size_t>{}(n);
for( auto&& x : c)
retval = hash_combine( retval, hash<T>{}(x) );
return retval;
}
template<class T0, class C>
constexpr size_t custom_hash_container( C const& c) {
return custom_hash_container( c.size(), c );
}
template<class T, class...Ts>
size_t custom_hash( std::vector<T, Ts...> const& v ) {
return custom_hash_container<T>(v);
}
template<class T, class...Ts>
size_t custom_hash( std::basic_string<T, Ts...> const& v ) {
return custom_hash_container<T>(v);
}
template<class T, size_t n>
constexpr size_t custom_hash( std::array<T, n> const& v ) {
return custom_hash_container<T>(n, v);
}
template<class T, size_t n>
constexpr size_t custom_hash( T (const& v)[n] ) {
return custom_hash_container<T>(n, v);
}
// etc -- list, deque, map, unordered map, whatever you want to support
namespace details {
template<class T, class=void>
struct hash : std::hash<T> {};
using hashers::custom_hash;
template<class T>
struct hash<T,decltype(void(
custom_hash(declval<T const&>())
)) {
constexpr size_t operator()(T const& t)const {
return custom_hash(t);
}
};
}
template<class T>
struct hash : details::hash<T> {};
template<>
struct hash<void> {
template<class T>
constexpr size_t operator()(T const& t)const { return hash<T>{}(t); }
}
}
and now hashers::hash<T> will recursively use either an ADL-looked up custom_hash function, or std::hash if that fails, to hash T and its components, and hashers::hash<> is a universal hasher that tries to hash anything passed to it.
Code may not compile as shown.
I chose to hash all containers and tuples as hash their length, followed by hashing the combination of their contents. As a side effect, array<int, 3> hashes the same as tuple<int,int,int>, and tuple<int,int> hashes the same as pair<int,int>, and std::vector<char>{'a','b','c', '\0'} hashes the same as "abc", which I think is a nice property. The empty array/tuple/vector/etc hashes like size_t(0).
You can extend the above system for your own types by simply overriding custom_hash in the namespace of the type in question, or specializing either std::hash<X> or hashers::hash<X> to do your custom hash (I would go with std::hash for the principle of least surprise myself). For advanced use, you can specialize hashers::details::hash<X,void> with SFINAE, but I'd say do it for custom_hash instead.

How to get dereferenced type of template member for function return type

How can I get the correct type T for the following function to_vector?
template<typename K> struct A { K* p; size_t n; std::string foo; };
template<typename K> struct B { K* p; size_t n; float bar[3]; };
template<typename X>
std::vector<T> to_vector(const X& x) { // what is T?
return std::vector<T>(x.p, x.p+x.n);
}
I tried with decltype(*std::declval<X>().p) but this results in error: forming pointer to reference type ‘float&’ for the following example:
A<float> a = { new float[10], 10, "hello" };
std::vector<float> v = to_vector(a);
This is part of some bigger code and there are more types like A and B. But all have a pointer p and a length n.
You can probably use
typename std::decay<decltype(*X::p)>::type
for T because decltype is an unevaluated context and hence X::p is legal here. Also, std::decay seems like a good fit as it combines std::remove_reference with std::remove_cv.
This answer is pretty much obsolete now.
template<typename X, typename T = typename std::remove_reference<decltype(*X().p)>::type>
std::vector<T> to_vector(const X& x)
{
return std::vector<T>
(x.p, x.p+x.n);
}
You are on the right track, you just need to use appropriate utility to get rid of the pointer/reference.
There is std::remove_reference, which you can use like:
typename std::remove_reference<decltype(*std::declval<X>().p)>::type
but it's a bit simpler to std::remove_pointer instead:
typename std::remove_pointer<decltype(std::declval<X>().p)>::type
(see, the * is gone, otherwise the same).
You might want to throw in std::remove_cv into the mix if the pointer might be cv-qualified, because vector elements shouldn't be.
As noted in the other, now deleted answer, you can write x.p instead of std::declval<X>().p if you use the trailing return type declaration:
template <typename X>
auto to_vector(const X& x) ->
std::vector<typename std::remove_pointer<decltype(x.p)>::type>
So here is an answer completely out of left field.
You should turn your types A and B into iterable objects by overloading begin and end in their namespace.
There are multiple approaches for this:
1) You enforce that each of them implement a member-begin and member-end that returns a pointer as an iterator. Alternatively a free function begin and end that does the same thing.
2) You require that they inherit from a CRTP helper class that does the above -- it either implements begin and end for you, or it enables a free function begin and end overload that can be seen with ADL.
3) If all such classes are in some namespace that you control, and you want to treat the K* p and std::size_t n fields as evidence that it should be treated as an iterable range, then we can do it with a "global" begin and end that uses SFINAE to only apply in that case.
I would advise #1 or #2.
For #2:
template<typename Derived>
struct p_n_iterable {
Derived* self() {
static_assert( std::is_base_of<p_n_iterable, Derived>::value, "CRTP failure" );
return static_cast<Derived*>(this);
}
Derived const* self() const {
static_assert( std::is_base_of<p_n_iterable, Derived>::value, "CRTP failure" );
return static_cast<Derived const*>(this);
}
typedef typename std::decay< decltype( *Derived::p ) >::type value_type;
typedef value_type* iterator;
std::size_t size() const { return self()->n; }
iterator begin() { return self->p; }
iterator end() { return begin() + size(); }
};
if I wrote that right, change A to read:
template<typename K> struct A : p_n_iterable<A<K>> { ... unchanged ... };
and all of a sudden for( auto x:a ) type loops work on A.
I think the cost, of having to add that little preamble to the classes, is so worth it for the feature.
To do this with #3, we create a traits class that detects if it should be n_p_iterable by checking that T::n is of type std::size_t and T::p is a pointer type. I'd advise against this, for while it requires less boilerplate elsewhere, it is pretty hacky.
Once we have this, we can write a really generic to_vector.
To start with, we write ourself a get_iterator_type<Container>:
namespace adl_helper {
using std::begin; using std::end;
template<typename C>
auto adl_begin(C&& c)->decltype(begin( std::forward<C>(c) ));
template<typename C>
auto adl_end(C&& c)->decltype(end( std::forward<C>(c) ));
}
using adl_helper::adl_begin;
using adl_helper::adl_end;
template<typename... Ts> struct type_sink { typedef void type; }
template<typename... Ts> using TypeSink = typename type_sink<Ts...>::type;
template<typename Container, typename=void>
struct get_iterator_type {};
template<typename Container>
struct get_iterator_type< Container, TypeSink< adl_begin( std::declval<Container&>() ) > > {
typedef adl_begin( std::declval<Container&>() ) type;
};
template<typename Container, typename=void>
struct get_value_type {};
template<typename Container>
struct get_value_type< Container, TypeSink< std::iterator_traits< typename get_iterator_type<Container>::type > > > {
typedef std::iterator_traits< typename get_iterator_type<Container>::type > > traits;
typedef typename traits::value_type type;
};
now, we write our to_vector:
template<typename C>
auto to_vector( C&& container )->
std::vector<typename get_value_type<typename remove_reference<C>::type>::type>
{
std::vector<typename get_value_type<typename remove_reference<C>::type>::type> retval;
for( auto&& x : std::forward<C>(container) ) {
retval.push_back(x);
}
return retval;
}
and if I dotted all the is and crossed all the ts you now have both full C++11 style iteration on your types and a to_vector that works on both your types, and other iterable containers (such as a std::map).
Further improvements can include detecting if the container passed in has a size or has random-access iterators, and if so reserving size in retval. But this post is long enough.
One can use traits :
template<typename K> struct A { K* p; size_t n; std::string foo; typedef K my_type; };
template<typename K> struct B { K* p; size_t n; float bar[3]; typedef K my_type; };
template<typename X>
std::vector<typename X::my_type> to_vector(const X& x) {
return std::vector<typename X::my_type>(x.p, x.p+x.n);
}
A<float> a = { new float[10], 10, "hello" };
std::vector<float> v = to_vector(a);

A puzzle for template wizards

I'd like to do the following:
const int someInt;
const std::vector<int> someIntList;
const std::vector<std::vector<int>> someNestedIntList;
Marshall(someInt); // trivial case
Marshall(someIntList); // difficult case
Marshall(someNestedIntList); // difficult case
I tried the following:
template<std::vector<class Element>>
void Marshall(const std::vector<Element>& toBeMarshalled)
{
for (int i=0; i<toBeMarshalled.size(); ++i)
Marshall<Element>(toBeMarshalled[i]);
}
Regrettably, this doesn't compile, and I failed to find the right syntax for it.
Note that there has to be only a single template parameter, otherwise the marshalling of a nested list won't work.
Update: Thanks to FredOverflow's answer, I found what I was looking for. I forgot that all container classes in the standard library have a value_type typedef. This can be used as a workaround for my problem:
template <class Container>
void Marshall(const Container& toBeMarshalled)
{
for (UINT32 i=0; i<toBeMarshalled.size(); ++i)
Marshall<Container::value_type>(toBeMarshalled);
}
It is a bit of a patch, but I think it is good enough.
There are two things wrong with your template:
The template declaration is wrong. You only list the template arguments here, not the function argument types. Also, >> is parsed as shift operator.
std::vector has two template parameters. Although in your daily work you will rarely use the second, it's still there and should be listed, or your template will fail if anyone ever attempts to use it with a std::vector that doesn't use the default allocator.
This should work for all std::vector instances:
template< typename T >
void Marshall(const T& toBeMarshalled)
{
// ...
}
template< typename T, class A >
void Marshall(const std::vector<T,A>& toBeMarshalled)
{
for (typename std::vector<T,A>::size_type i=0; i<toBeMarshalled.size(); ++i)
Marshall(toBeMarshalled[i]);
}
The template declaration is wrong. Do:
template< class Element >
void marshall( std::vector< Element > const& v )
Cheers & hth.,
May I propose SFINAE and some boost metaprogramming?
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
template <class T>
struct has_begin_end
{
template <class U,
typename U::const_iterator (U::*)() const,
typename U::const_iterator (U::*)() const>
struct sfinae { };
template <class U>
static char test(sfinae<U, &U::begin, &U::end>*);
template <class>
static long test(...);
enum { value = (1 == sizeof test<T>(0)) };
typedef boost::integral_constant<bool, value> type;
};
template <class Value>
typename boost::disable_if<has_begin_end<Value>, void>::type
Marshall(const Value& value)
{
std::cout << value << ' ';
}
template <class Container>
typename boost::enable_if<has_begin_end<Container>, void>::type
Marshall(const Container& c)
{
std::for_each(c.begin(), c.end(), Marshall<typename Container::value_type>);
}
int main()
{
const int someInt = 42;
const std::vector<int> someIntList {2, 3, 5, 7};
const std::vector<std::vector<int>> someNestedIntList {{11, 13}, {17, 19}};
Marshall(someInt);
Marshall(someIntList);
Marshall(someNestedIntList);
}
The code you've pasted contains >> at the end of your template declaration. C++ compilers will interpret that not as two closing angle brackets, but as a single right-shift operator.
Try template<std::vector<class Element> >, with a space between the brackets.