说明符。是的,声明者。它们是许多编码约定辩论的来源。对于参数来说这是一个非常好的主题--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) { }
有关具体示例,请点击here。
所以,我的问题是: 为什么我们仅限于此(合法)表单而不能使用另一个?
有什么想法吗?
附加1:我也对设计决定感兴趣,为什么这条“规则”被“强制执行”。
答案 0 :(得分:4)
旧的声明符语法只是一个带有微不足道的空格的规则,但你的想法是两个。我怀疑委员会会赞成在一个足够的情况下制定两条规则。
将声明者放在左侧的选择很可能有两个原因:
int* x
而不是int *x
(例如Bjarne使用前者)。大多数人认为声明者语法是错误的。...
左侧,而不是右侧。答案 1 :(得分:3)
首先,我不会说int &a
比int& a
更有效。你可能会说它更具可读性或者是一种好的做法,但这完全是另一回事。
其次,参数解包语法T...
可以读作“扩展...
左侧的类型模式,形成与表单匹配的相同或不同的实际函数参数类型类型模式“。因此,当您撰写f(T&...)
时,可以将其展开为f(int&, float&, double&, Xyz&, Abc&)
。但是当语法为T...&
时,这似乎并不那么明显(至少对我而言)。所以,也许这就是为什么标准这样做的其他几个可能的原因之一。
另请注意,args
中的T&...args
可选。所以,如果你不写它,那么void f(T...&)
看起来很奇怪(至少对我来说),而void f(T&...)
至少看起来更美观。
您还可以将T * const & ...
和T... * const &
等语法进行比较。 type-pattern 在前一种语法中比在后一种语法中更明显。
答案 2 :(得分:2)
实现完美,而不是在没有其他任何东西可以添加的情况下,但是当没有任何东西可以带走时。
- Antoine de Saint-Exupery
编程语言设计的难点不是添加功能,而是不添加功能。每个功能,每种语法变体都有成本:
C和C ++中的语法(大多数)是空格不敏感的,因此放置&
或*
的位置并不重要,两个首选项可以共存而不会有额外的负担;但是对于可变参数模板,由于...
令牌,它确实很重要。因此,委员会选择了一个,他们选择了C ++中最惯用的(强调完整类型而不是基类型)。