【问题标题】:Compile error with variadic templates and overloaded << operator使用可变参数模板和重载 << 运算符编译错误
【发布时间】:2017-04-05 11:05:56
【问题描述】:

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

代码:

#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&lt;...&gt;&amp; 作为参数重载“

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。你能帮我解决这个问题吗?谢谢。

这个问题似乎和this post中描述的类似。

我还有一个额外的问题(但这也许应该转到另一篇文章)。是否有更通用的方法将原始类型的参数包转换为这些类型的向量元组?根据模板参数数量的增加,将 VectorTuple 的不同变体的显式枚举替换为如下所示:

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

这样

TransformToVectors<double, int, float>::type

将是

的别名
std::tuple<std::vector<double>, std::vector<int>, std::vector<float>>

我尝试从具有较少模板参数的实例递归地构建类型,但没有走得很远。

【问题讨论】:

  • 听起来像一个错误。已提交78457
  • 感谢您提交错误报告。
  • @Barry 不是编译器错误。在gcc.gnu.org/bugzilla/show_bug.cgi?id=69116#c2 中查看我对类似情况的分析
  • @T.C.但是根据[temp.deduct.call]/6,函数参数只有函数类型、函数指针类型、或成员函数类型的指针才是非推导上下文,即不是这里的情况。我错过了什么?
  • @bogdan [temp.deduct.type]/5.5。 IOW, [temp.deduct.call]/6 必须被解读为不暗示您添加的“唯一”。

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


【解决方案1】:

关于奖金问题

是否有更通用的方法来转换参数包 原始类型到这些类型的向量元组?会很好 替换不同变体的显式枚举 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>...>; };

?

【讨论】:

  • 这没什么问题 :) 我不知道这是可能的。谢谢。
猜你喜欢
  • 2019-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多