c++ - 如何检查mpl::vector_c中的值?

标签 c++ boost metaprogramming

the tutorial中是exersize,在需要的地方:

add error checking to the binary template causes a compilation error if N contains digits other than 0 or 1



通过标准功能可以很简单地做到这一点:

template <int N>
struct Binary {
  static_assert(N == 0 || N == 1, "binary have to be 0 or 1");
  const int n = N;
};

但是如何通过mpl::vector_c实现呢?例如:

using values = mpl::vector_c<int, 0, 1>;

template<int N,
         typename = typename std::enable_if</*TODO compare N with values from mpl::vector_c*/>::type>
struct Binary {
  const int n = N;
};

最佳答案

建立在the other answer之上,
在下面,您可以通过使用enable_if找到使用SFINAE的解决方案,如问题所示。

这比我最初预期的要复杂一些,因为在某种程度上,部分模板特化中为boost::mpl_vector_c提供的参数数量与mpl::vector的大小不匹配。

因此,我在下面定义了一个辅助结构,该结构允许对提供的 bool(boolean) 值可变参数模板的子集执行 bool(boolean) “和”运算。

如果c++ 17可用,则可以替换注释c++ 14 / c++ 17标记的行。
如果c++ 14不可用,则可以通过在struct中使用递归#value声明和分别由_v替换的_t / [...]::value/type后缀来替换index_sequence。


#include <boost/mpl/vector_c.hpp>

#include <tuple>

/// Helper struct which enables to evaluate a conjunction of a subset of a set of booleans.
template <typename IndexSequence, bool... v> struct PartialConjunction;
/// Parital template specialization
template <std::size_t... idx, bool... b>
struct PartialConjunction<std::index_sequence<idx...>, b...>
    : std::integral_constant<
          bool, (std::get<idx>(std::forward_as_tuple(b...)) && ...)> {};
/// 'Alias' for the value 
template <std::size_t S, bool... v> constexpr auto PartialConjunction_v =
    PartialConjunction<decltype(std::make_index_sequence<S>()), v...>::value;


/// Actual struct which holds the type of the vector in ::type if it meets the criterion
template <typename VecType, VecType N, typename MplVector> struct Same; //< c++14
//template <auto N, typename MplVector> struct Same;                    //< c++17
template <typename VecType, VecType N, long... a> struct Same<VecType, N, boost::mpl::vector_c<VecType, a...>> {// c++14
//template <typename VecType, VecType N, long... a> struct Same<N, boost::mpl::vector_c<VecType, a...>> {       // c++17
  using type = boost::mpl::vector_c<VecType, a...>;
  static constexpr auto Size = typename type::size();
  static constexpr auto value = PartialConjunction_v<Size, N == static_cast<VecType>(a)...>;
};
/// Alias for the type which performs SFINAE.
template <typename T, T N, typename VectorType, typename = std::enable_if_t<Same<T, N, VectorType>::value>>  // c++14..
using Same_t = typename Same<T, N, VectorType>::type;
//template <auto N, typename VectorType, typename = std::enable_if_t<Same<N, VectorType>::value>>            // c++17..
//using Same_t = typename Same<N, VectorType>::type;



int main() {

  // For the c++17 version, the first 'int' in the parameter list can be omitted

  //Same_t<int, 1, boost::mpl::vector_c<int, 1, 1, 2>> fails;

  Same_t<int, 1, boost::mpl::vector_c<int, 1, 1, 1>> ok;
  Same_t<int, 1, boost::mpl::vector_c<int, 1, 1>> okok;
  Same_t<int, 1, boost::mpl::vector_c<int, 1>> okokok;
}


该代码示例可以在CompilerExplorer中的here中找到。

关于c++ - 如何检查mpl::vector_c中的值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60474712/

相关文章:

c++ - 删除了所有自动生成的构造函数/运算符的类仍然可以从函数返回吗?

c++ - 从共享库导出模板化 C++ 类在 Linux 上如何工作?

ruby - 将现有类添加到模块中

c++ - 从文件中获取数据时如何放置换行符?

c++ - 我可以用 typedef 对类非静态成员方法做什么

c++ - 使用 system() 时如何处理路径中的空格?

c++ - 在 Makefile 中查找 Boost 库

c++ - 对共享变量执行多个原子操作

c++ - 循环中的模板元编程?

java - 元编程 - 自解释代码 - 教程、文章、书籍