C++:将迭代器传递给函数的语法?

4
我正在制作一个类,它是一种容器,我想制作一个构造函数,可以像std::vector和其他标准容器一样使用“first”和“last”迭代器。正确的语法是什么?(我想要一个模板函数,可以使用任何可用的first/last迭代器类型(就像标准库一样)。非常感谢!)
例如,我想要这样的东西:
template<class ...> MyClass(... first, ... last) 

但是什么是...?

非常感谢。

关于第一个答案: 我需要一个特定的构造函数,以迭代器作为参数(因为我已经有了以值和指针作为参数的构造函数)。

编辑: 像这样的东西可以吗?

template<class T1, class T2> MyClass(std::iterator<T1, T2> first, std::iterator<T1, T2> last)

那么,你有一个很大的设计问题。正如我在我的答案中指出的那样,“通用迭代器”类型只是一个模板。你可以限制模板,以便只有迭代器可以被传递,但是你的其他构造函数存在歧义情况。那个其他的构造函数具体用于什么? - Xeo
我在我的问题中添加了一个示例。通过通用迭代器,我指的是从std :: iterator派生出来的东西。 - Vincent
没有std::iterator类,也没有其他常见的迭代器基类。 - Xeo
@JerryCoffin:哦,对了。那就不用理会我上一条评论了。 - Xeo
@Xeo:从(小)技术上讲,你实际上是正确的:std::iterator不是一个类,而是一个模板。没有通用的迭代器基类,因为该模板在不同类型上的每个实例化都是完全独立的类型。 - Jerry Coffin
显示剩余5条评论
2个回答

6
< p > ... 可以是任何你想要的,它只是一个占位符名称,用于表示类型。我认为你需要阅读一本好书

template<class Iter> MyClass(Iter first, Iter last)

Iter 是一个常见的名称,如果该类型应表示迭代器。另一个选项可能是 InIt,以表明这些迭代器不应为输出迭代器。


不是我,但也许应该是typename Iter? - helloworld922
2
@helloworld922:不是的,当用于模板参数时,“class”和“typename”是同义词。但请注意,只有在使用模板模板参数时才能使用“class”:template<template<typename> class TemplClass> - Xeo
@helloworld922,从本质上讲,两者都没有更好的选择。这个类只是有点多余了。 - chris
2
这里 class 的使用很好。在《现代 C++ 设计》一书中,Andre 建议在任何类型可以传递时使用 typename,而在需要用户定义类型时使用 class,但这似乎从未真正流行起来。 - Jerry Coffin

3

我认为你可以利用 std::iterator 具有一个名为 iterator_category 的成员来实现你想要的功能。将其与SFINAE结合使用,您可以得到以下代码:

#include <iostream>
#include <vector>

template <class X>
class my_class {
public:
    my_class(X a, X b) {
        std::cout << "in my_class(X,X)" << std::endl;
    }

    template <class Iter>
    my_class(Iter a, Iter b, typename Iter::iterator_category *p=0) {
        std::cout << "in my_class(Iter,Iter)" << std::endl;
    }
};

int
main()
{
    char buf[] = "foo";
    std::vector<char> v;

    my_class<int> one(1, 2);
    my_class<char*> two(&buf[0], &buf[3]);
    my_class<char> three(v.begin(), v.end());

    return 0;
}

这将打印:

in my_class(X,X)
in my_class(X,X)
in my_class(Iter,Iter)

太好了!我不知道SFINAE,它可以非常有用。 - Vincent
1
除了指针是有效的迭代器且明显不具备“iterator_category”类型定义之外。 - Xeo
@Xeo "指针是有效的迭代器" 这取决于您对迭代器的定义。如果您将其定义为具有 std::iterator 成员,则指针不是一个很好的迭代器。 - D.Shawley
1
iterator_traits 正是为这种情况而存在的。这就是为什么你应该使用 typename iterator_traits<Iter>::iterator_category 而不是仅仅使用 Iter::iterator_category - sbabbi
@D.Shawley:除了迭代器是基于指针建模的这一点非常重要。 - Xeo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接