繁体   English   中英

使用可变参数模板和重载<<运算符编译错误

[英]Compile error with variadic templates and overloaded << operator

我正在尝试创建一个存储向量元组的类。 我有一个奇怪的编译错误,其起源我不明白。

编码:

#include <iostream>
#include <tuple>
#include <vector>

/// Suppose T is a pack of primitive types
/// VectorTuple defines a tuple of vectors of these types

template <typename... T>
struct VectorTuple;

template <typename T>
struct VectorTuple<T>
{
  using data_type = std::tuple<std::vector<T>>;
};

template <typename T1, typename T2>
struct VectorTuple<T1, T2>
{
  using data_type = std::tuple<std::vector<T1>, std::vector<T2>>;
};

template <typename T1, typename T2, typename T3>
struct VectorTuple<T1, T2, T3>
{
  using data_type = std::tuple<std::vector<T1>, std::vector<T2>, std::vector<T3>>;
};

// ----------------------------------------------------------------------------

template <size_t I, size_t N, typename... T>
struct DataAlgorithm
{
  static void resize(typename VectorTuple<T...>::data_type &data, const size_t size)
  {
    std::get<I>(data).resize(size);
    DataAlgorithm<I + 1, N, T...>::resize(data, size);
  }
};

// ----------------------------------------------------------------------------

template <size_t N, typename... T>
struct DataAlgorithm<N, N, T...>
{
  static void resize(typename VectorTuple<T...>::data_type &data, const size_t size)
  {
    std::get<N>(data).resize(size);
  }
};

// ----------------------------------------------------------------------------

template <typename... StoredTypes>
class MultiArray
{

public:
  enum
  {
    NFields = sizeof...(StoredTypes)
  };

  using value_types = std::tuple<StoredTypes...>;

  void resize(const size_t size)
  {
    DataAlgo<0, NFields - 1, StoredTypes...>::resize(m_values, size);
  }

private:
  template <size_t I, size_t N, typename... T>
  using DataAlgo = DataAlgorithm<I, N, T...>;

  using storage_type = typename VectorTuple<StoredTypes...>::data_type;

  /// The actual data stored
  storage_type m_values;
};


// This doesn't compile when array is const&, but works with non-const reference
template <typename... StoredTypes>
std::ostream &operator<<(std::ostream &os, const MultiArray<StoredTypes...> &array)
{
  os << std::endl; // This is line 86 in the compiler error message
  return os;
}

int main()
{
  MultiArray<double, int, float> array;

  return 0;
}

我无法使用const MultiArray<...>&作为参数重载“<<”运算符。 Clang 3.9.0说:

compile_error.cpp: In instantiation of ‘class MultiArray<>’:
compile_error.cpp:86:14:   required from here
compile_error.cpp:75:71: error: invalid use of incomplete type ‘struct VectorTuple<>’
   using storage_type = typename VectorTuple<StoredTypes...>::data_type;
                                                                       ^
compile_error.cpp:9:8: note: declaration of ‘struct VectorTuple<>’
 struct VectorTuple;

如果我理解正确,编译器无法推断出参数类型并尝试实例化VectorTuple带任何参数。 你能帮帮我解决这个问题吗? 谢谢。

这个问题似乎是类似于中描述的这个帖子

我也有一个奖金问题(但这可能应该转到另一个帖子)。 是否有更通用的方法将基本类型的参数包转换为这些类型的向量元组? VectorTuple根据增加的模板参数数量替换VectorTuple的不同变体的显式枚举,如下所示:

template<typename ... T> struct TransformToVectors { /* ?? implementation ?? */ };

这样的

TransformToVectors<double, int, float>::type

将是别名

std::tuple<std::vector<double>, std::vector<int>, std::vector<float>>

我试图从具有较少数量的模板参数的实例中递归地构建类型,但是没有达到很远。

对于奖金问题

是否有更通用的方法将基本类型的参数包转换为这些类型的向量元组? 最好根据增加的模板参数数量替换VectorTuple的不同变体的显式枚举,如下所示:

 template<typename ... T> struct TransformToVectors { /* ? implementation ?? */ }; 

这样的

 TransformToVectors<double, int, float>::type 

将是别名

 std::tuple<std::vector<double>, std::vector<int>, std::vector<float>> 

怎么了?

template<typename ... T>
struct TransformToVectors
 { using type = std::tuple<std::vector<T>...>; };

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM