语义迭代器声明?

发布于 2024-11-10 00:24:55 字数 577 浏览 2 评论 0原文

我很抱歉这个非常模糊的标题,我真的不知道如何命名这个问题。

假设我有这个:

std::list<std::string> msgs;

for (std::list<std::string>::iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

对我来说,这很难阅读。 std::list::iterator 几乎看起来像一个神奇的数字,特别是如果 msgs 的声明很远,比如在头文件中。在我看来,如果它是这样的,它会更容易阅读并且更具语义:

std::list<std::string> msgs;

for (msgs.iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

现在,这显然是非法的 C++。但我的问题是,有没有一种方法可以实现支持像这样编写迭代器声明的东西?

I'm sorry for the very vague title, I really didn't know how to title this question.

Let's say I have this:

std::list<std::string> msgs;

for (std::list<std::string>::iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

For me, this is hard to to read. The std::list<std::string>::iterator almost seems like a magic number, especially if the declaration of msgs is far away, like in an header file. IMO it would be easier to read and much more semantic if it were something like this:

std::list<std::string> msgs;

for (msgs.iterator it = msgs.begin(); it < msgs.end(); it++) {
    // ...
}

Now, this is obviously illegal C++. But my question is, is there a way of implementing something that supports writing iterator declarations like this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

梦晓ヶ微光ヅ倾城 2024-11-17 00:24:55

如果您提供 typedef,它将使生活变得更加轻松:

typedef std::list<std::string>::iterator ListIterator;
for( ListIterator it = msgs.begin(); it != msgs.end(); ++it ){}

除此之外,c++0x 通过提供 auto 关键字来为您做到这一点:

for( auto it = msgs.begin(); it != msgs.end(); ++it ){}

edit 就像日期后 5 年一样,但我更新了 < tp != 并使用预增量,因为这实际上是我多年来一直在做的事情,并且对我来说更有意义,以至于它让我想知道我是如何写的这个答案不使用那个

If you provide a typedef it will make life a lot easier:

typedef std::list<std::string>::iterator ListIterator;
for( ListIterator it = msgs.begin(); it != msgs.end(); ++it ){}

Other than that, c++0x does it for you by providing the auto keyword:

for( auto it = msgs.begin(); it != msgs.end(); ++it ){}

edit like 5 years after date, but I updated < tp != and using preincrement because that's actually what I've been doing for ages, and makes more sense to me, to the point it makes me wonder how I ever wrote this answer not using that

清风夜微凉 2024-11-17 00:24:55

有两种实用的规范方法:

typedef std::list<int> list_t;
list_t l;

// later:
for (list_t::iterator it = l.begin(), end = l.end(); it != end; ++it) {}

以及仅限 C++0x auto

std::list<int> l;

// later:
for (auto it = l.begin(), end = l.end(); it != end; ++it) {}

此外,C++0x 允许:

std::list<int> l;

// later:
for (decltype(l)::iterator it = l.begin(), end = l.end(); it != end; ++it)
   std::cout << *it << ", ";

我认为这是与您具体情况最接近的匹配询问(即使这不一定是最好的解决方案)。

缺点是能够将作用域运算符 (::) 应用于 decltype link 最近才被投票纳入工作文件,我不知道任何支持它的编译器(GCC 4.5.1 )。

There are two practical, canonical approaches:

typedef std::list<int> list_t;
list_t l;

// later:
for (list_t::iterator it = l.begin(), end = l.end(); it != end; ++it) {}

And the C++0x-only auto:

std::list<int> l;

// later:
for (auto it = l.begin(), end = l.end(); it != end; ++it) {}

In addition, C++0x allows:

std::list<int> l;

// later:
for (decltype(l)::iterator it = l.begin(), end = l.end(); it != end; ++it)
   std::cout << *it << ", ";

I think that this is the closest match to what you were specifically asking (even if it's not necessarily the best solution).

The downside is that the ability to apply the scope operator (::) to decltype link was only voted into the working paper relatively recently, and I'm not aware of any compilers that support it yet (GCC 4.5.1 does not).

别再吹冷风 2024-11-17 00:24:55

您可以使用 typedef 来清理它:

typedef std::list<std::string>::iterator string_iterator;

std::list<std::string> msgs;

for (string_iterator it = msgs.begin(); it != msgs.end(); it++) {
    // ...
}

You can use typedef to clean that up:

typedef std::list<std::string>::iterator string_iterator;

std::list<std::string> msgs;

for (string_iterator it = msgs.begin(); it != msgs.end(); it++) {
    // ...
}
謸气贵蔟 2024-11-17 00:24:55

所有容器都具有这些 typedef 来支持编写非常通用的代码。考虑以下函数模板:

template<class T>
void foo(const T& container) {
    for(T::const_iterator it = T.begin(); it != T.end(); it++) {
        // do stuff
    }
}

这使您能够编写可与定义类型 const_iterator 和方法 begin()end 的任何对象一起使用的代码()

在 C++0x 中,通过引入 auto 关键字解决了该问题:

for(auto it = container.begin(); it != container.end(); it++) {
    // do stuff
}

All containers have these typedefs to enable the writing of very generic code. Consider the following function-template:

template<class T>
void foo(const T& container) {
    for(T::const_iterator it = T.begin(); it != T.end(); it++) {
        // do stuff
    }
}

This enables you to write code that can work with any object that has defines a type const_iterator and a method begin() and end().

In C++0x the problem is solved with the introduction of the auto keyword:

for(auto it = container.begin(); it != container.end(); it++) {
    // do stuff
}
苦妄 2024-11-17 00:24:55

规范的解决方案是

std::for_each(msgs.begin(), msgs.end(), ... );

在 C++0x 之前,编写 ... 位曾经有点困难(如果它很复杂的话),但我们现在有了 lambda。

The canonical solution is

std::for_each(msgs.begin(), msgs.end(), ... );

Before C++0x, writing the ... bit used to be a bit hard (if it was anything complex), but we now have lambda's.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文