【发布时间】:2017-12-28 10:51:54
【问题描述】:
这是我的问题Implement STL functions in variadic template的延续:
如果已经定义了用作array[indx0][indx1]…[indxN] 的“单层”下标运算符,我如何为接受长度为N 的数组的N 维数组实现下标运算符。我觉得应该有一个简单的折叠表达式?
【问题讨论】:
标签: c++ arrays templates variadic-templates c++17
这是我的问题Implement STL functions in variadic template的延续:
如果已经定义了用作array[indx0][indx1]…[indxN] 的“单层”下标运算符,我如何为接受长度为N 的数组的N 维数组实现下标运算符。我觉得应该有一个简单的折叠表达式?
【问题讨论】:
标签: c++ arrays templates variadic-templates c++17
因此,[] 不是可折叠运算符之一。真可惜。但我们只需要稍微作弊,然后搭上另一个 :)
namespace indexer_detail {
template <class T>
struct ArrayWrapper {
T obj;
};
template <class T>
ArrayWrapper(T&&) -> ArrayWrapper<T&&>;
template <class T>
auto operator & (ArrayWrapper<T> const &aw, std::size_t N) {
return ArrayWrapper{aw.obj[N]};
}
}
template <std::size_t Size, class Array, std::size_t... Idx>
decltype(auto) index(
Array &&array,
std::array<std::size_t, Size> const &indices,
std::index_sequence<Idx...>
) {
return (
indexer_detail::ArrayWrapper{std::forward<Array>(array)} & ... & indices[Idx]
).obj;
}
template <std::size_t Size, class Array>
decltype(auto) index(Array &&array, std::array<std::size_t, Size> const &indices) {
return index(std::forward<Array>(array), indices, std::make_index_sequence<Size>{});
}
【讨论】:
因为它是 C++17,我们可以使用 constexpr if 让它变得更简单:
template<size_t Idx0, size_t... IdxRest, typename V>
decltype(auto) getval(const V& v)
{
if constexpr (sizeof...(IdxRest) == 0)
{
return v[Idx0];
}
else
{
return getval<IdxRest...>(v[Idx0]);
}
}
int main()
{
int arr[10][10] = { 1,2,3 };
std::vector<int> arr2 = { 1,2,3 };
auto v1 = getval<0, 2>(arr);
auto v2 = getval<1>(arr2);
return 0;
}
【讨论】: