C++ 可变参数模板 : remove/replace type at index

标签 c++ templates c++11 variadic-templates template-meta-programming

有没有办法:

1) 删除索引处的项目:

// Removes item at index N, e.g. Remove<2, a, b, c, d> results in <a, b, d>
template<std::size_t N, typename ...Args>
struct Remove {
    // ???
};

2) 替换索引处的项目:

// Replaces item at index N with T, e.g. Replace<2, x, a, b, c, d> results in <a, b, x, d>
template<std::size_t N, typename T, typename ...Args>
struct Replace {
    // ???
};

3) 替换范围内的项目

// Replaces items in range [N1, N2] with T, e.g. ReplaceRange<2, 3, x, a, b, c, d> results in <a, b, x>
template<std::size_t N1, std::size_t N2, typename T, typename ...Args>
struct ReplaceRange {
    // ???
};

我希望它能像那样使用

class is_true {
public:
    bool operator()() const { return true; }
};


class is_false {
public:
    bool operator()() const { return false; }
};

class And {
};

class Or {
};

Filter f<is_true, And, is_true, Or, is_false>();

现在,我想把它折成:

< FilterOr < FilterAnd <is_true, is_true>, is_false > >

在哪里

template<typename Lhs, typename Rhs>
class FilterAnd {
public:
    bool operator()() const { return Lhs() && Rhs(); }
};

template<typename Lhs, typename Rhs>
class FilterOr {
public:
    bool operator()() const { return Lhs() || Rhs(); }
};

所以,我正在尝试执行以下操作:

class Filter {
public:
    template <typename ...Args>
    void apply() {
        holder_ = FilterHolder<typename FoldOperator<Or, FilterOr, typename FoldOperator<And, FilterAnd, Args...>::type >::type >();
    }
}

FoldOperator基本上删除运算符参数,并将运算符替换为 Filter类,例如参数<is_true, And, is_true> , 我想删除参数 ( is_true ) 并将运算符 ( And ) 替换为 Filter: FilterAnd<is_true, is_true>其中参数与从列表中删除的参数相同。因此,我需要替换/删除模板来执行此操作。

提前致谢。

最佳答案

这在 C++14 中使用 std::index_sequence 更容易,所以我使用了它。您可以在线找到大量的实现方式。

我使用 std::tuple 来整理周围的一切。

对于 Replace,我使用 std::conditional 为每个类型索引选择 T 或正确的元组元素。

对于 Remove,我采用 tuple_catdecltype 为未删除的空元组或包含正确元组元素的元组类型索引。

namespace detail{
template<std::size_t N, typename T, typename Tuple, std::size_t... Idx>
auto replace (std::index_sequence<Idx...>) ->
    std::tuple<std::conditional_t<N == Idx, 
                                  T, 
                                  std::tuple_element_t<N, Tuple>>...>;

template<std::size_t N, typename Tuple, std::size_t... Idx>
auto remove (std::index_sequence<Idx...>) ->
    decltype(std::tuple_cat(
      std::declval<
        std::conditional_t<(N == Idx), 
                           std::tuple<>, 
                           std::tuple<std::tuple_element_t<Idx, Tuple>>
      >
    >()...
    ));
}

template <std::size_t N, typename T, typename... Args>
using Replace = decltype(detail::replace<N,T,std::tuple<Args...>>
                         (std::index_sequence_for<Args...>{}));

template <std::size_t N, typename... Args>
using Remove = decltype(detail::remove<N,std::tuple<Args...>>
                        (std::index_sequence_for<Args...>{})); 

ReplaceRange 留给读者作为练习。

Live Demo

关于C++ 可变参数模板 : remove/replace type at index,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34680414/

相关文章:

c++ - G++ 编译器无法识别 C++ 中的枚举类型

c++ - 是什么阻止 g++ 消除运行时未使用的临时 std::array ?

c++ - 如何使用已删除的复制构造函数初始化类数组(C++11)

c++ - C++ 在执行多态性时是否接受内联虚函数?

c++ - 如何在先前输入后在 C++ 中使用 "gets"函数?

c++ - 如果函数值为 null 则返回

c++ - bool 表达式中带有 strlen() 的奇怪行为

c++ - §14/2 中的 "last component"一词的含义是什么?

在 CPP 文件 (Visual Studio) 中实现的 C++ 模板错误

c++ - std::tr1::function 和 std::tr1::bind