【问题标题】:Swap two parameters in variadic template交换可变参数模板中的两个参数
【发布时间】:2018-02-16 18:42:43
【问题描述】:

我正在尝试交换参数包的两项。

理想情况下,我想做这样的事情:

template<int i1, int i2, class... Args>
void swapped_copy(some_class a, some_class b, Args... args) {
    a(args...) = b(/* 'args...' where parameters with indices i1 and i2 are swapped */);
}

有什么想法吗?

非常感谢。

【问题讨论】:

  • 我知道这是一个骗局,但我不记得它出现的背景,所以我不知道该搜索什么了。

标签: c++ c++11 variadic-templates


【解决方案1】:

您可以使用 std::tuple 来打包 args 并按索引解包,并使用 std::index_sequence 来生成要使用的索引。然后只需对索引进行交换即可。像这样的:

namespace swapped_copy_detail {
    constexpr std::size_t swap_one_index(
        std::size_t i1, std::size_t i2, std::size_t index) {
        return index==i1 ? i2 : (index==i2 ? i1 : index);
    }

    template <std::size_t i1, std::size_t i2, class Tuple, std::size_t... Inds>
    void do_swapped_copy(
        some_class& a, some_class& b,
        Tuple&& args,
        std::index_sequence<Inds...> inds ) {
        a(std::get<Inds>(args)...) =
            b(std::get<swap_one_index(i1, i2, Inds)>(args)...);
    }
}

template <std::size_t i1, std::size_t i2, class ...Args>
void swapped_copy(some_class a, some_class b, const Args& ...args) {
    static_assert(i1 < sizeof...(Args) && i2 < sizeof...(Args),
                  "Index too large for swapped_copy");
    swapped_copy_detail::do_swapped_copy<i1, i2>(
        a, b, std::tie(args...),
        std::index_sequence_for<Args...>());
}

index_sequenceindex_sequence_for 在 C++14 标准中,但您的问题被标记为 [c++11]。如果您需要坚持使用 C++11,可以在 this answer 中找到这些实用程序的实现。

【讨论】:

  • 应该将 forward_as_tuple 用于这种事情,而不是 tie。
  • @NirFriedman 我之前基本上是这样的,但是每个参数都使用了两次,所以在这种情况下转发它们并不是一个好主意。
  • 确实,这似乎是要走的路。谢谢。
猜你喜欢
  • 2014-08-01
  • 1970-01-01
  • 2016-12-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-09
  • 2013-09-14
  • 1970-01-01
  • 2013-09-22
相关资源
最近更新 更多