宏 - 好,坏还是难看? [英] Macros - Good, bad, or ugly?

查看:127
本文介绍了宏 - 好,坏还是难看?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个我无法解决的问题,至少让我满意......



我想出的最佳解决方案远涉及使用宏。 (我知道......)



IDE:Visual Studio 2012



I came across a problem that I was unable to solve, at least to my satisfaction...

The best solution I''ve came up with so far involves using a macro. (I know...)

IDE: Visual Studio 2012

void main()
{
    std::vector<int>; numbers;
    numbers.push_back(100);
    numbers.push_back(200);
    numbers.push_back(300);

    // I'm not typing all of this every single time...
    numbers.erase(std::remove(numbers.begin(), numbers.end(), 200), numbers.end());

    // Better, but still, no.. (Having to supply the type really brings it down.)
    Vector::Erase<int>(numbers, 200); // See below for code

    // Nice.
    VECTOR_REMOVE(numbers, 200); // See below for code

    // I wish... :(
    numbers.Remove(200); // Doesn't really exist...   

    // I also tried making my own list type which used vector internally.
    // That way I could create the member method as shown above.
    // However, it had issues, and was dropped in favor of the other methods.
    // It was also the most work, since I had to re\create all the functionality.
    // In it's defense, the resulting interface was really nice. (Think C# List<T>)

    numbers.clear();
}

namespace Vector
{
    // Erase
    template <typename T>;
    void Erase(std::vector<T>& source, T item)
    {
        source.erase(std::remove(source.begin(), source.end(), item), source.end());
    }
}

#define VECTOR_REMOVE(vector, value) vector.erase(std::remove(vector.begin(), vector.end(), value), vector.end());





此问题远远超出此范围一个例子,幸运的是,Boost已经从中拯救了我很多,但是,仍然存在很多问题。



这个话题的真正问题:



在上面的场景中宏是否可以,如果没有,有人可以指向一个更好的解决方案,并且使用相同或更少量的代码作为我当前的宏解决方案吗? />


这样的宏怎么样?





This problem extends far beyond this one example, thankfully, Boost has saved me from much of it, however, many problems still exist.

The real question of this topic:

Is a macro okay in the above scenario, if not, can someone point me towards a better solution that works, and uses the same or less amount of code as my current macro solution?

What about macros like this?

#define FOR(var, iterations) for (int var=0; var < iterations; ++var)

FOR(i, 10)
 std::cout << "Hello World!" << std::endl;





我主要使用的是宏片段可能会有效,但是,宏在视觉上产生的代码较少在我看来,这使得寻找更清洁的解决方案。



想法?邪恶?好的?嗯?



---



注意:我搜索了Google,以及大多数宏观讨论提到logging \ theader guard,数学你不应该使用宏,我发现这些类型的解决方案没有一个主题,以及它们是否可以接受。



I''m mainly using macros where snippets would probably work, however, macros produce less code ''visually'' which makes for cleaner looking solutions, in my opinion.

Thoughts? Evil? Okay? Meh?

---

Note: I''ve searched Google, and most macro discussions mention logging\header guards, and math you shouldn''t be doing with macros, none of the topics that I found addressed these types of solutions, and whether they were acceptable or not.

I''m actually undecided, that''s why I''m asking for your advice on the matter, and perhaps, you guys can supply me with some other options that I''ve overlooked too. :D

推荐答案

首先:

First:
// Better, but still, no.. (Having to supply the type really brings it down.)
Vector::Erase<int>(numbers, 200); // See below for code
Vector::Erase(numbers, 200); // <-- This works well enough





我对宏没有问题,但我可能会像对于我可以合理期望的东西,例如JDERT_FOR或其他东西......



祝你好运

Espen Harlinn



I''ve got no problems with macros, but I would proably prefix something like FOR with something I can reasonably expect to be unique, like JDERT_FOR or something ...

Best regards
Espen Harlinn


虽然有一些例外支持使用宏,但你给出的例子是明确的NO-GO!原因如下:



1.宏污染全局命名空间:如果您打算在本地使用它们(即只在一个cpp单位内),那么可读性和打字的安全时间是一个很好的论据,因为地方几乎都是nixes。如果不在本地使用,宏名称将在整个解决方案中可见,并可能与其他代码冲突,包括第三方库!



示例:我已经由于 max 宏(在其中一个windows标题中定义,不会少!)导致这样的错误,因为它炸毁了stof的微软实现:: vararray(也有一个名为 max 的函数)

2.宏不是类型安全的,通常很难调试。



3.您提供的示例可以轻松实现为全局函数或模板函数。那些是类型安全的,可以包含在命名空间中以避免冲突。



4.在宏观中引入错误太容易了立即出现,反而将困扰未来的程序员。由于这些错误的结果通常无法追溯到它的原因,它们将需要进行全面的代码分析。



5。你的推理是值得怀疑的:我个人更喜欢原始的显式版本,因为我理解它们并且确切知道它们的作用。即使我不知道,当我没有正确使用它们时,它们定义的类型安全性肯定会导致编译器错误。然而,宏不熟悉 - 我必须相信他们做了什么*我相信他们所做的事情,如果他们不做,那么任何事情都可能发生。为了避免这种情况,我必须查找定义并理解它们。即便如此,如果我犯了错误,产生的错误信息可能不会告诉我实际原因!也没有暗示如何解决它!



结论:如果你自己做一个项目,没有其他人参与,你不打算把它当作别人的图书馆,然后做你觉得最舒服的事。如果没有,那么请为自己和其他所有人节省很多痛苦并避免那些不必要的宏。



PS:

想想以下问题:

您是否可以在不访问编译器的情况下编写无错代码?



如果是,请随时使用宏。

如果不是,那么你编写的任何宏都必然导致很难修复错误。



因为编写宏就像关闭编译器语法分析一样。
While there are exceptions in favor of using macros, the examples you''ve given are a definitive NO-GO! Here are the reasons:

1. Macros pollute the global namespace: if you intend to use them locally (i. e. within just one cpp unit), then neither the readability nor the safed time for typing are a good argument, as the locality pretty much nixes both. If not used locally, the macro names will be visible within the entire solution and may potentially conflict with other code, including third party libraries!

Example: I''ve once spent a full week due to such an error caused by a max macro (defined in one of the windows headers, no less!), because it blew up Microsofts implementation of std::vararray (which also has a function called max)
2. Macros are not typesafe, and generally hard to debug.

3. The examples you''ve given can easily be implemented as global functions, or template functions. Those would be typesafe and could be included in a namespace to avoid conflicts.

4. It''s way too easy to introduce mistakes in a macro that don''t immediately show up and instead will plague future programmers. Since the result of such mistakes will usually be impossible to trace back to it''s cause, they will instead require a full-blown-code analysis.

5. Your reasoning is doubtful: personally I prefer the original explicit version, as I understand them and know precisely what they do. Even if I don''t, the typesafety of their definition will liekly result in a compiler error when I don''t use them correctly. The Macros however are unfamiliar - I have to trust they do what *I* believe what they do, and if they don''t, then anything can happen. To avoid that, I have to look up the definitions, and understand them. And even then, if I make an error, the resulting error messages will likely not show me the actual cause! Nor give a hint how to fix it!

Conclusion: If you do a project all on your own, with no-one else involved, and you do not intend to ship it as a library for others, then do whatever you feel most comfortable with. If not, then save yourself and everyone else a whole lot of pain and avoid those unneccesary macros.

P.S.:
Think about the following question:
Can you write error-free code without access to a compiler?

If yes, feel free to use macros whenever you like.
If no, then any macro you write is bound to cause hard to fix errors.

Because writing macros is like switching off compiler syntax analysis.


为什么不继承向量并实现删除函数(你想要的)。这将是解决问题的一种方式。
Why don''t you inherit vector and implement Remove function(that you so want). That would be one way of going about it.


这篇关于宏 - 好,坏还是难看?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆