您最喜欢的 C++ 是什么?成语?

发布于 2024-10-07 09:04:55 字数 686 浏览 0 评论 0原文

可能的重复:
您最喜欢的 C++ 编码风格习惯用法是什么

亲爱的 C++ 粉丝,

您能在这里列出您最喜欢的 C++ 习惯用法吗?最好列出那些有用但不为人所知的。

首先,我放了我的一个:

为了避免繁琐的重复 for (size_t i = 0; i < n; ++i) {...} ,我使用这样的宏:

#define LOOP(n) for (size_t _i = 0; _i < n; ++_i)

_i is绑定使用的占位符。

所以我可以写:

vector<int> coll(100);
LOOP (100)
{
    coll[_i] = _i;
}

LOOP (100)
{
    auto a = _i;
    LOOP (100)
    {
        auto b = _i;
        cout << a << b;
    }
}

Possible Duplicate:
What are your favorite C++ Coding Style idioms

Dear C++ fans,

Could you list here your favorite C++ idioms? It is better to list those which are useful yet not well-known.

Firstly, I put one of mine:

To avoid tedious repeating for (size_t i = 0; i < n; ++i) {...} , I use a macro like this:

#define LOOP(n) for (size_t _i = 0; _i < n; ++_i)

_i is a placeholder as bind uses.

So I can write:

vector<int> coll(100);
LOOP (100)
{
    coll[_i] = _i;
}

LOOP (100)
{
    auto a = _i;
    LOOP (100)
    {
        auto b = _i;
        cout << a << b;
    }
}

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

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

发布评论

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

评论(4

叹倦 2024-10-14 09:04:55

RAII 位于我的列表的顶部。在很多情况下它都会派上用场......

作为通用实现最有用,例如 Andrei Alexandrescu 的

RAII is on the top of my list. There are so many cases when it just comes in handy...

Most useful as a generic implementation like Andrei Alexandrescu's libloki.

生死何惧 2024-10-14 09:04:55

好问题,但我认为你的例子很糟糕!你的 LOOP 宏并没有让任何东西变得更清晰 - 它实际上向不使用你的宏的程序员隐藏了你的意图,而且它甚至看起来不像 C++ - 我对你的代码片段的第一反应是“这还是C++吗?”或者“普通的 for 有什么问题吗?”。一遍又一遍地编写循环可能很乏味,但我们都知道每个人花在阅读和维护代码上的时间比编写代码的时间要多得多,因此编写完整的 for< 并不是浪费时间。 /code>,这样就清楚多了。您可以继续争论您的观点,但您应该意识到,以这种方式使用宏不是一种被广泛接受的技术 - 其他查看您代码的人也会对您提出批评。

无论如何,添加一个实际的答案 - 我在 C++0x 中最喜欢的习惯用法是 unique_ptr 的向量:

std::vector<std::unique_ptr<T>> my_container;

它具有以下优点 - 本质上是一个安全的指针向量:

  • 它在 O(1) 时间内提供随机访问
  • 元素保证永远不会即使在重新分配时也会在内存中移动(这样您就可以安全地获取 T 的地址并存储它们)
  • 对于排序等任务来说速度很快(只是打乱一些指针,而不是复制重量级对象)
  • 异常安全并有助于防止内存占用泄漏 - 元素上的 erase() 也会释放内存
  • 灵活 - 您可以将 std::move() 指针移出容器并将它们放在其他地方

它确实有一个或两个缺点:

  • 每个元素都在堆上分配,如果添加/删除大量元素,可能会对性能产生影响,而且元素在内存中可能相距很远,从而丢失缓存局部性
  • 迭代需要双重间接(*i​​)-> member 语法 - 但我认为这没什么大不了的

但是,特别是对于重量级对象,我认为它几乎是一个理想的容器。

Good question but I think your example is a bad one! Your LOOP macro does not make anything clearer - it actually hides your intent from programmers who don't use your macro, and it doesn't even look like C++ - my first reaction to your snippet would be "is that even C++?" or "what's wrong with an ordinary for?". It may be tedious to write the loops over and over, but we all know everyone spends a lot more time reading and maintaining code than writing it in the first place, so it's hardly a waste of time writing out a full for, and it's much clearer. You can continue to argue your point, but you should be aware that using macros in that way is not a widely accepted technique - other people looking at your code will call you out on it too.

Anyway, to add an actual answer - my favourite idiom in C++0x is a vector of unique_ptr:

std::vector<std::unique_ptr<T>> my_container;

It has the following advantages - essentially a safe vector of pointers:

  • It provides random access in O(1) time
  • Elements are guaranteed to never move in memory even when reallocating (so you can safely take the address of Ts and store them)
  • Fast for tasks like sorting (just shuffling some pointers, not copying heavyweight objects)
  • Exception safe and helps prevent memory leaks - erase() on an element also releases the memory
  • Flexible - you can std::move() pointers out of the container and put them somewhere else

It does have one or two disadvantages:

  • Each element is allocated on the heap which may have performance implications if adding/removing a lot of elements, plus elements can be far apart in memory losing cache locality
  • Iteration requires double indirection (*i)->member syntax - but I don't think it's a big deal

However, especially for heavyweight objects, I think it is nearly an ideal container.

孤独患者 2024-10-14 09:04:55

RAII + 如果需要精确的生命周期范围,则打开嵌套块:

Lock lock(this);
ResourceHolder resource(findResource());
WorkerHolder worker(resource);
if (!worker)
    return false; // frees the resource and unlocks the lock
{
    WorkAssignment assignment(worker);
    assignment.Execute();
} // assignment cleaned up even in case of exception
...

RAII + opening a nested block if exact lifetime scope needed:

Lock lock(this);
ResourceHolder resource(findResource());
WorkerHolder worker(resource);
if (!worker)
    return false; // frees the resource and unlocks the lock
{
    WorkAssignment assignment(worker);
    assignment.Execute();
} // assignment cleaned up even in case of exception
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文