【问题标题】:Class that accepts iterator as argument, and stores values?接受迭代器作为参数并存储值的类?
【发布时间】:2017-08-05 23:34:45
【问题描述】:

假设我想实现一个在某个范围内迭代的类,并将这些值存储在随机索引的数组中。所以我想要一些我可以写的东西:

string s = "Steve";
auto r1 = RandomArray<char>(s.begin(), s.end());
int a[] = {1,2,3};
auto r2 = RandomArray<int>(begin(a), end(a));
// Later on...
for (const auto ch: r1) {/* do something */}

我将如何定义这样一个类?我无法弄清楚模板应该是什么样子。也就是下面缺的怎么填?

// template stuff
class RandomArray {
    public:
    RandomArray(/* some iterator argument(s) */) {
        // Pretend arr_ has already been sized correctly.
        for (const auto it = /* iterate over iterator */) {
            arr_[randomIndex()] = it;
        }
    }
    private:
    /* Some type */ arr_[];
};

我忽略了我最终需要的所有其他东西(移动构造函数、开始/结束等)。我只是想弄清楚类之前的模板语句应该是什么样子。

【问题讨论】:

  • 您真正需要的是用户指定的模板推导指南,它是在 C++17 中引入的。
  • 你认为arr_ 的类型会神奇地依赖于运行时调用的RandomArray 构造函数吗?那不会飞的您可以使RandomArray 成为根据元素类型参数化的类模板,然后像MakeRandomArray 这样的函数模板将根据其参数制造正确的特化。类似于std::make_pair。或者,我可能完全误解了问题的本质;对练习的最终目标进行更完整的解释可能会有所帮助。
  • @IgorTandetnik:我希望 arr_ 的类型对应于迭代器的值类型。我只是不知道如何表达。 “更好”的构造函数的目的是简单地强调我不想传递开始/结束,而是传递可迭代本身。您可以将其视为主要问题的次要问题。
  • @IgorTandetnik:我很高兴有一个单独的函数来创建实例。我只是不知道那个函数的模板是什么样子的
  • 您有 RandomArray&lt;string&gt;(s.begin(), s.end()) 采用值为 char(不是 string)的迭代器。然后你有RandomArray&lt;int&gt; 采用迭代器,其值实际上是intRandomIterators 模板参数的假定作用是什么?是元素的类型、容器的类型还是其他?

标签: c++ c++11 templates iterator


【解决方案1】:

类似的东西(未经测试):

template <typename Elem>
class RandomArray {
public:
  template <typename InputIter>
  RandomArray(InputIter first, InputIter last)
    : storage(first, last) {}

  template <typename Container>
  explicit RandomArray(const Container& c)
    : storage(std::cbegin(c), std::cend(c)) {}

  // For C-style array
  template <typename Elem2, size_t N>
  explicit RandomArray(Elem2 (&arr)[N])
    : storage(std::cbegin(arr), std::cend(arr)) {}

private:
  std:vector<Elem> storage;
};

template <typename InputIter>
auto MakeRandomArray(InputIter first, InputIter last) {
  return RandomArray<typename std::iterator_traits<InputIter>::value_type>(
    first, last);
}

template <typename Container>
auto MakeRandomArray(const Container& c) {
  return RandomArray<typename Container::value_type>(c);
}

// For C-style array
template <typename Elem, size_t N>
auto MakeRandomArray(Elem (&arr)[N]) {
  return RandomArray<Elem>(arr);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-16
    • 2017-04-23
    • 1970-01-01
    相关资源
    最近更新 更多