10

声明者。是的,声明者。它们是许多编码约定辩论的根源。对于争论来说,这是一个非常好的话题——C++ 并不规定哪一个比另一个更好(它不在乎!)。所以我们可以写这些而不用担心有人会取笑你:

int x;

int& a = x;
int &b = x;

int* c = &x;
int *d = &x;

在句法方面,b并且d比其他“更有效”。我们需要在名称之前放置声明符修饰符:

int m, *n;   // m is an int; n is a pointer to int

但潮流似乎转向了有利于一个。使用 C++11 的可变参数模板,声明符的位置似乎仅限于修饰符更接近基类型的形式:

template<typename... Ts>
void VariadicFuncRef(const Ts&... args) { }
                             ^
template<typename... Ts>
void VariadicFuncPtr(Ts*... args) { }
                       ^

写这些表格是错误的:

template<typename... Ts>
void VariadicFuncRef(const Ts... &args) { }

template<typename... Ts>
void VariadicFuncPtr(Ts... *args) { }

有关具体示例,请单击此处

所以,我的问题是: 为什么我们仅限于这种(合法的)形式而不能使用另一种?

有什么想法吗?

附加1:我也对为什么这个“规则”“强制执行”的设计决定感兴趣。

4

3 回答 3

4

旧的声明符语法只是一个带有微不足道的空格的规则,但您的想法是两个。我怀疑委员会是否会赞成制定两条规则,如果一条就足够了。

选择将声明符放在左边很可能有两个原因:

  • 如今,惯用的 C++ 更喜欢int* x而不是int *x(例如,Bjarne 使用前者)。大多数人认为声明符语法是错误的。
  • 参数包扩展将内容扩展到 的左侧,而...不是右侧。
于 2012-12-19T07:55:12.693 回答
3

首先,我不会说int &a比. 您可能会说它更具可读性,或者是一种好的做法,但这完全是另一回事。int& a

其次,参数解包语法T...可以理解为“将左侧的类型模式...展开,形成与类型模式形式匹配的相同或不同的实际函数参数类型”。所以当你写的时候f(T&...),它可以扩展为f(int&, float&, double&, Xyz&, Abc&). 但是当语法是T...&. 所以也许,这就是标准做出那样的其他几个可能原因之一。

另请注意,argsinT&...args可选的。所以如果你不写它,那么void f(T...&)看起来很奇怪(至少在我看来)并且至少void f(T&...)在美学上看起来更好。

您还可以比较 :T * const & ...T... * const &. 类型模式在前一种语法中比在后者中更明显。

于 2012-12-19T07:53:13.853 回答
2

达到完美,不是在没有什么可以添加的时候,而是在没有什么可以带走的时候。

——安托万·德·圣埃克苏佩里

编程语言设计的难点不是添加特性,而是避免添加它们。每一个特性,每一个语法变体,都有代价:

  • 它们必须在编译器中专门编码
  • 它们有引入错误的风险
  • 它们存在与另一个特征/变体发生不良交互的风险
  • ...

C 和 C++ 中的语法(大部分)对空格不敏感,因此无论您将&or*和两个首选项放在哪里都可以共存而无需额外负担;然而,在可变参数模板的情况下,由于...令牌,它确实很重要。委员会因此决定选择一个,他们选择了 C++ 中最惯用的一个(强调完整类型而不是基本类型)。

于 2012-12-19T08:39:57.810 回答