pre*_*eys 3 c++ templates c++11
Swap<T, Position1, Position2, Pack>::type,其中Pack包含类型T的元素,是返回包含Position1和Position2中的元素的包.我的解决方案不是最有效的.应该有一种方法可以非常干净地完成这项任务,而无需两次访问任何元素.有人能想到吗?
// ReplaceElement replaces the element of a pack with a specified position (0 being the first position) with a specified value.
template <typename T, std::size_t, std::size_t, T, typename, typename> struct ReplaceElementHelper;
template <typename T, std::size_t Position, std::size_t CurrentPosition, T NewValue, template <T...> class Z, T First, T... Rest, T... Accumulated>
struct ReplaceElementHelper<T, Position, CurrentPosition, NewValue, Z<First, Rest...>, Z<Accumulated...>>
: ReplaceElementHelper<T, Position, CurrentPosition + 1, NewValue, Z<Rest...>, Z<Accumulated..., First>> {};
template <typename T, std::size_t Position, T NewValue, template <T...> class Z, T First, T... Rest, T... Accumulated>
struct ReplaceElementHelper<T, Position, Position, NewValue, Z<First, Rest...>, Z<Accumulated...>> {
using type = Z<Accumulated..., NewValue, Rest...>;
};
template <typename T, std::size_t, T, typename> struct ReplaceElement;
template <typename T, std::size_t Position, T NewValue, template <T...> class Z, T... Ts>
struct ReplaceElement<T, Position, NewValue, Z<Ts...>> : ReplaceElementHelper<T, Position, 0, NewValue, Z<Ts...>, Z<>> {
static_assert (Position < sizeof...(Ts), "Error! Invalid position for ReplaceElement.");
};
// Swapping two elements of specified positions in a pack.
template <typename, std::size_t, std::size_t, typename> struct Swap;
template <typename T, std::size_t Position1, std::size_t Position2, template <T...> class Z, T... Ts>
struct Swap<T, Position1, Position2, Z<Ts...>> {
static constexpr T a[sizeof...(Ts)] = {Ts...};
using type = typename ReplaceElement<T, Position2, a[Position1], typename ReplaceElement<T, Position1, a[Position2], Z<Ts...>>::type>::type;
};
Run Code Online (Sandbox Code Playgroud)
您可以告诉我的解决方案all在Position1(或Position2)之前访问元素两次.应该没有必要.我知道必须有一个避免这种情况的解决方案,但我无法想到它.
如果value_pack定义有点像
template <typename T, T... v>
struct value_pack {
static constexpr T array[] {v...};
static constexpr std::size_t len = sizeof...(v);
using type = value_pack;
};
template <typename T, T... v>
constexpr T value_pack<T, v...>::array[];
Run Code Online (Sandbox Code Playgroud)
那么C++ 14中的解决方案如下所示:
template <typename T, std::size_t p1, std::size_t p2,
typename pack,
typename=std::make_index_sequence<pack::len>>
struct Swap;
template <typename T, std::size_t p1, std::size_t p2,
typename pack, std::size_t...indices>
struct Swap<T, p1, p2, pack, std::index_sequence<indices...>> :
value_pack<T, pack::array[indices==p1? p2 : indices==p2? p1 : indices]...> {};
Run Code Online (Sandbox Code Playgroud)
演示.如果没有C++ 14标准库,您可以make_index_sequence自己实现- 许多示例分散在SO中.
| 归档时间: |
|
| 查看次数: |
116 次 |
| 最近记录: |