如何通过icpc17编译使用递归可变参数模板的c ++代码?

时间:2019-01-18 15:32:22

标签: c++ variadic-templates icc

我想用icpc 17编译器(icpc (ICC) 17.0.4 20170411)编译矩阵矢量乘积的基于可变参数模板的版本。代码编译时对clang和gcc都没有任何问题。但是,使用icpc,编译似乎挂起了(我等待了大约一个小时)。 有人知道我在这里遇到的icpc的已记录错误吗?如果有人知道,如何解决该错误?

#ifndef UTILS_MATRIX_VECTOR_PRODUCT_HPP
#define UTILS_MATRIX_VECTOR_PRODUCT_HPP

#include <array>
#include <utility>

namespace Utils {

namespace detail {

template <int c, typename T> struct mul {
  constexpr T operator()(const T a) const { return c * a; }
};

template <typename T> struct mul<0, T> {
  constexpr T operator()(const T a) const { return T{}; }
};

template <typename T> struct mul<1, T> {
  constexpr T operator()(const T a) const { return a; }
};

template <int I, typename T, std::size_t N, int c, int... cs>
struct inner_product_template_impl {
  constexpr T operator()(std::array<T, N> const &a) const {
    return mul<c, T>{}(std::get<I>(a)) +
           inner_product_template_impl<I + 1, T, N, cs...>{}(a);
  }
};

template <int I, typename T, std::size_t N, int c>
struct inner_product_template_impl<I, T, N, c> {
  constexpr T operator()(std::array<T, N> const &a) const {
    return mul<c, T>{}(std::get<I>(a));
  }
};

template <typename T, std::size_t N,
          const std::array<std::array<int, N>, N> &matrix,
          std::size_t row_index, std::size_t... column_indices>
constexpr T inner_product_helper(const std::array<T, N> &vec,
                                 std::index_sequence<column_indices...>) {
  return inner_product_template_impl<
      0, T, N, std::get<column_indices>(std::get<row_index>(matrix))...>{}(vec);
}

template <typename T, std::size_t N,
          const std::array<std::array<int, N>, N> &matrix,
          std::size_t row_index>
constexpr T inner_product_template(const std::array<T, N> &vec) {
  return detail::inner_product_helper<T, N, matrix, row_index>(
      vec, std::make_index_sequence<N>{});
}

template <typename T, std::size_t N,
          const std::array<std::array<int, N>, N> &matrix,
          std::size_t... column_indices>
constexpr std::array<T, N>
matrix_vector_product_helper(const std::array<T, N> &vec,
                             std::index_sequence<column_indices...>) {
  return std::array<T, N>{
      {inner_product_template<T, N, matrix, column_indices>(vec)...}};
}

} // namespace detail

template <typename T, std::size_t N,
          const std::array<std::array<int, N>, N> &matrix>
constexpr std::array<T, N> matrix_vector_product(const std::array<T, N> &vec) {
  return detail::matrix_vector_product_helper<T, N, matrix>(
      vec, std::make_index_sequence<N>{});
}

} // namespace Utils

#endif

对于一个有效的示例,可以使用以下源文件:

#include <array>
#include <iostream>

#include "matrix_vector_product.hpp"

static constexpr const std::array<std::array<int, 19>, 19>
    matrix =
    {{{{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
      {{0, 1, -1, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0}},
      {{0, 0, 0, 1, -1, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1}},
      {{0, 0, 0, 0, 0, 1, -1, 0, 0, 0, 0, 1, -1, -1, 1, 1, -1, -1, 1}},
      {{-1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
      {{0, 1, 1, -1, -1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, -1, -1, -1, -1}},
      {{-0, 1, 1, 1, 1, -2, -2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1}},
      {{0, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0}},
      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1, 0, 0, 0, 0}},
      {{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, -1, -1}},
      {{0, -2, 2, 0, 0, 0, 0, 1, -1, 1, -1, 1, -1, 1, -1, 0, 0, 0, 0}},
      {{0, 0, 0, -2, 2, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, 1, -1, 1, -1}},
      {{0, 0, 0, 0, 0, -2, 2, 0, 0, 0, 0, 1, -1, -1, 1, 1, -1, -1, 1}},
      {{0, -0, 0, 0, 0, 0, 0, 1, -1, 1, -1, -1, 1, -1, 1, 0, 0, 0, 0}},
      {{0, 0, 0, -0, 0, 0, 0, 1, -1, -1, 1, 0, 0, 0, 0, -1, 1, -1, 1}},
      {{0, 0, 0, 0, 0, -0, 0, 0, 0, 0, 0, 1, -1, -1, 1, -1, 1, 1, -1}},
      {{1, -2, -2, -2, -2, -2, -2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}},
      {{0, -1, -1, 1, 1, -0, -0, 0, 0, 0, 0, 1, 1, 1, 1, -1, -1, -1, -1}},
      {{0, -1, -1, -1, -1, 2, 2, 2, 2, 2, 2, -1, -1, -1, -1, -1, -1, -1, -1}}}};

int main() {
    std::array<double, 19> vector{{4,3,5,2,3,4,5,6,6,4,24,7,8,2,3,9,2,32,2}};
    auto const result = Utils::matrix_vector_product<double, 19, matrix>(vector);
    for (auto const& res : result) {
        std::cout << res << "\n";
    }
    return 0;
}

我尝试用

进行编译
icpc -std=c++14 main.cpp

0 个答案:

没有答案