Reputation: 6679
How can I wrap T**
to give it std::vector<std::vector<T>>
semantics? All solutions I have found so far address a single dimension.
The use case is to pass both T**
and std::vector<std::vector<T>>
to a function that consumes matrix data.
template<class RowIt>
void foo(RowIt rowFirst, RowIt rowLast) {
// size doesn't handle dynamically allocated arrays
size_t columns = std::size(*rowFirst);
// second layer std::begin, std::end and iterator doesn't
// work for dynamically allocated arrays
for (; rowFirst != rowLast; ++rowFirst) {
auto colFirst = std::begin(rowFirst);
auto colLast = std::end(rowFirst);
for (; colFirst != colLast; ++colFirst) {
// processing logic
}
}
}
I attempted to extend the single dimension solution to multi dimension. The problem I run into is
template<class T>
class view {
T* data_;
};
view<view<T>>
can't be composed from view<T>
.
Upvotes: 1
Views: 79
Reputation: 62809
You can add a partial specialisation for nested views
.
template<class T>
class view {
using pointer = T*;
pointer data_;
};
template<class T>
class view<view<T>> {
using pointer = typename view<T>::pointer *;
pointer data_;
};
Or specify view::pointer
via a traits class, if it is the only divergence from the primary template
template<class T>
class view_traits {
using pointer = T*;
};
template<class T>
class view_traits<view<T>> {
using pointer = typename view<T>::pointer *;
};
template<class T>
class view {
using pointer = typename view_traits<T>::pointer;
pointer data_;
// other members use T unchanged
};
Upvotes: 1