I'm trying to solve a college problem, that, among other things, requires us to write a function which takes a parameter: container of Type1, that contains containers of Type2, which contain containers of Type3, which contain elements of an arbitrary type. The container types do not have to be different, but all that is known is that they support only a few functions (e.g. size( )), and that all the dimensions are the same. We've only dealt with sequence containers so far, so I presume they'll be testing this with custom sequence containers.
What I need is a function that returns a Type2 container that contains Type1 containers. I tried to use a construction like this:
template <typename Cube>
auto foo(const Cube &bar) -> remove_reference<decltype(bar)>
{
auto square(remove_reference<decltype(bar)> {});
cout << square.size(); // Throws an error
return square;
}
Hoping that decltype would help me make a Type2 container that contains Type1 containers. However, when i call the function with a 3D vector as a parameter:
int main() {
vector<vector<vector<int>>> v {{{1}}};
foo(v);
}
It throws an error:
error: no member named 'size' in 'std::remove_reference<const std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > > &>'
cout << square.size();
~~~~~~ ^
note: in instantiation of function template specialization 'foo<std::vector<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > >, std::allocator<std::vector<std::vector<int, std::allocator<int> >, std::allocator<std::vector<int, std::allocator<int> > > > > > >' requested here
foo(v);
^
I have poor knowledge of C++ types, so I don't really understand what type is "deduced" here. We've covered very little ground surrounding decltype and function templates, and nothing else we've covered that could help comes to mind. We're not allowed to use so much outside our curriculum (C++11 only) so I presume that either I've made a rookie mistake somewhere or there's a more elegant way of doing this.
EDIT: the return value and square should be have been specified as
auto square(remove_reference<decltype(bar[0])> {});
remove_reference<decltype(bar)>
is not removing the reference from decltype(bar)
- you need
typename remove_reference<decltype(bar)>::type
Read the remove_reference
documentation.