我一直都这么问,但我从来没有得到过一个非常好的答案; 我认为,在写第一个"Hello World"之前,几乎所有程序员都遇到过"宏不应该使用宏","宏是邪恶的"这样的短语等等,我的问题是:为什么?有了新的C++ 11,这么多年后还有一个真正的选择吗?
简单的部分是关于宏#pragma,特定于平台和特定于编译器,并且大多数时候它们具有严重的缺陷,例如#pragma once在至少两种重要情况下容易出错:不同路径中的相同名称以及一些网络设置和文件系统.
但总的来说,宏的用法和替代品呢?
我不明白为什么初始化程序列表不能用于运算符的RHS.考虑:
class foo { };
struct bar
{
template<typename... T>
bar(T const&...) { }
};
foo& operator<<(foo& f, bar const&) { return f; }
int main()
{
foo baz;
baz << {1, -2, "foo", 4, 5};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
最新的Clang(gcc也)抱怨:
clang.cc:14:9: error: initializer list cannot be used on the right hand side of operator '<<'
baz << {1, -2, "foo", 4, 5};
^ ~~~~~~~~~~~~~~~~~~~~
^ ~~~~~~~~~~~~~~~
Run Code Online (Sandbox Code Playgroud)
为什么C++标准会禁止这个?或者换句话说,为什么这会失败而不是
baz << bar{1, -2, "foo", 4, 5};
Run Code Online (Sandbox Code Playgroud)
?
假设我有一堆众所周知的值,就像这样(但const char *只是一个例子,它可能会更复杂):
const char *A = "A", *B = "B", *C = "C", *D = "D", *E = "E", *F = "F", *G = "G";
Run Code Online (Sandbox Code Playgroud)
现在让我们说如果某个表达式的结果位于其中的一个子集中,我希望以特定方式运行:
if (some_complicated_expression_with_ugly_return_type == A ||
some_complicated_expression_with_ugly_return_type == C ||
some_complicated_expression_with_ugly_return_type == E ||
some_complicated_expression_with_ugly_return_type == G)
{
...
}
Run Code Online (Sandbox Code Playgroud)
我发现自己经常输入这种东西,我想要一个简写.
如果语言是Python,我可以很容易地说:
if some_complicated_expression_with_ugly_return_type in [A, C, E, G]:
...
Run Code Online (Sandbox Code Playgroud)
有一种众所周知的,可移植的方式让我在C++ 03中表达同样的东西吗?
请注意,返回类型本身很难看(几乎和lambda表达式的返回类型一样难看),所以我当然不希望将它存储在局部变量中.
但返回类型并没有必须匹配的常量的-例如,如果返回类型是std::string,这将不会是隐式转换为const char *,但operator ==将是比较完美的罚款.
到目前为止,我所拥有的最佳解决方案是:
const char …Run Code Online (Sandbox Code Playgroud)