接收迭代器作为参数并知道类

时间:2018-01-10 17:57:32

标签: c++ templates

我需要创建一个接收迭代器作为参数的方法,并返回相同类型的模板化集合。

我创建了一个最小的例子来证明我的需要:

#include <list>
#include <iostream>

using namespace std;

class A {
    int i;
public:
    A(int _i) : i(_i) {}

    operator int() {
        return i;
    }
};

class B {
    int i;
public:
    B(int _i) : i(_i) {}

    operator int() {
        return i;
    }
};

template <class T>
list<T> method(typename list<T>::iterator begin, typename list<T>::iterator end) {
    list<T> res; // I need the template class here

    for (; begin != end; begin++) {
        cout << *begin; // Whatever...
    }

    return res;
}

int main() {
    list<A> listA = {1, 2, 3};
    list<B> listB = {4, 5, 6};

    auto res1 = method(listA.begin(), listA.end()); // Cannot change
    auto res2 = method(listB.begin(), listB.end()); // Cannot change
}

这不是一个有效的例子,但我正在寻找一种方法来实现这一目标。

重要的部分是method及其参数,它将返回带有T的模板化类。所以我可以根据需要更改方法,但auto res1 = method(listA.begin(), listA.end());应该保持不变。 (不是我的代码)

我该怎么办?

4 个答案:

答案 0 :(得分:2)

在这种特殊情况下(如果你知道它是std::list)你可以从迭代器本身获得value_type

template <class T>
auto method(T begin, T end) {
    list<typename T::value_type> res; // I need the template class here

    for (; begin != end; begin++) {
        cout << *begin; // Whatever...
    }

    return res;
}

value_type = U仅适用于std::list<U>

答案 1 :(得分:1)

typename list<T>::iteratora non-deduced context。您需要传递容器本身或将其指定为显式模板参数。

答案 2 :(得分:1)

迭代器指定序列;它们不必与“集合”相关联。例如,您可以创建一个从控制台读取输入的迭代器。

如果要将函数限制为仅使用容器,请按以下方式编写:

template <class T>
T f(const T& container) {
    // whatever; code that uses begin() and end()?
}

答案 3 :(得分:1)

这是不可能的。您可以拥有与任何容器都不对应的迭代器。调用方法的函数应创建一个空列表,并将back_inserter作为方法的第三个参数传递给列表。使用std:copy作为您的方法的示例。