- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
有人拥有 asked前几天为什么有些东西用clang编译,而不是用gcc编译。我直观地理解正在发生的事情并能够帮助这个人,但这让我想知道——根据标准,哪个编译器是正确的?这是代码的简化版本:
#include <iostream>
#include <string>
class foo
{
public:
foo(const std::string& x):
name(x)
{ }
foo& operator()(const std::string& x)
{
std::cout << name << ": " << x << std::endl;
return (*this);
}
std::string name;
};
int main()
{
std::string x = "foo";
foo(x)("bar")("baz");
return 0;
}
使用 clang++ 可以正常编译,但是 g++ 给出以下错误:
runme.cpp: In function ‘int main()’:
runme.cpp:21:11: error: conflicting declaration ‘foo x’
foo(x)("bar")("baz");
^
runme.cpp:20:17: error: ‘x’ has a previous declaration as ‘std::string x’
std::string x = "foo";
如果我在第 21 行添加一对括号,g++ 很高兴:
(foo(x))("bar")("baz");
换句话说,g++ 将这一行解释为:
foo x ("bar")("baz");
我认为它是 g++ 中的错误,但我想再次询问标准专家,哪个编译器出错了?
PS:gcc-4.8.3、clang-3.5.1
最佳答案
据我所知,这在草案 C++ 标准部分 6.8
歧义解决 中有所涉及,它说表达式语句和声明之间可能存在歧义,并说:
There is an ambiguity in the grammar involving expression-statements and declarations: An expression statement with a function-style explicit type conversion (5.2.3) as its leftmost subexpression can be indistinguishable from a declaration where the first declarator starts with a (. In those cases the statement is a declaration. [ Note: To disambiguate, the whole statement might have to be examined to determine if it is an expression-statement or a declaration. This disambiguates many examples. [ Example: assuming T is a simple-type-specifier (7.1.6),
并给出以下例子:
T(a)->m = 7; // expression-statement
T(a)++; // expression-statement
T(a,5)<<c; // expression-statement
T(*d)(int); // declaration
T(e)[5]; // declaration
T(f) = { 1, 2 }; // declaration
T(*g)(double(3)); // declaration
然后说:
The remaining cases are declarations. [ Example:
class T {
// ...
public:
T();
T(int);
T(int, int);
};
T(a); // declaration
T(*b)(); // declaration
T(c)=7; // declaration
T(d),e,f=3; // declaration
extern int h;
T(g)(h,2); // declaration—end example ] —end note ]
似乎这种情况属于声明示例,特别是最后一个示例似乎在 OP 中提出了这种情况,因此 gcc
将是正确的。
上面提到的相关部分5.2.3
显式类型转换(功能表示法)说:
[...] If the type specified is a class type, the class type shall be complete. If the expression list specifies more than a single value, the type shall be a class with a suitably declared constructor (8.5, 12.1), and the expression T(x1, x2, ...) is equivalent in effect to the declaration T t(x1, x2, ...); for some invented temporary variable t, with the result being the value of t as a prvalue.
和8.3
声明符的含义其中说:
In a declaration T D where D has the form
( D1 )
the type of the contained declarator-id is the same as that of the contained declarator-id in the declaration
T D1
Parentheses do not alter the type of the embedded declarator-id, but they can alter the binding of complex declarators.
更新
我最初使用的是 N337但是如果我们看一下 N4296 6.8
部分已更新,现在包含以下注释:
If the statement cannot syntactically be a declaration, there is no ambiguity, so this rule does not apply.
这意味着 gcc
不正确,因为:
foo x ("bar")("baz");
不能是一个有效的声明,我最初将第 2
段解释为如果你的 case 以以下任何一个开头,那么它就是声明,这可能是 gcc
实现者也被解释。
我应该对第 2
段更加怀疑,因为第 2
段的唯一规范部分确实没有提及第 1
段和似乎对一个不规范的例子提出了要求。我们可以看到,段落 2
中的语句现在实际上是一个更有意义的注释。
作为 T.C.如下所述,第 2
段实际上从来都不是规范的,它只是这样出现,他 linked to the change that fixed it .
关于c++ - g++ 拒绝,clang++ 接受 : foo(x) ("bar") ("baz");,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28283215/
我遇到了这段代码;我好奇地尝试编写类似的代码结构。我不谈论地理位置。 navigator.geolocation.getCurrentPosition(getPosition); fu
基本上我希望能够获取 url 的结尾,并将其转换为字符串以在某处使用。 目前我正在这样做(这不是最佳选择): // grab the path, replace all the forward sla
运行 Composer 的 update 时, install , require , dump-autoload , 等等。;我突然开始收到一条黄色的弃用通知,上面写着: Class Foo\Bar
我知道 & 会禁用原型(prototype),但括号也不会这样做。这两个代码块有什么不同,顶部不能像底部一样运行是否有原因, use List::Util; use constant FOO => (
我目前正在学习 JavaScript。我遇到了这个问题,并尝试在 javacript 中使用柯里化(Currying)来解决它,但无法完全正确地解决它。 给定一个函数 pipe(),它接受多个函数作为
我一直想知道 foo、bar、baz 等... 名字的意思。 我曾多次在科学文章中发现这些术语。此外,该术语以某种方式用作其他示例的标准。 有谁知道这些术语的来源,以及如何正确使用它们? 最佳答案 虽
指定如下规则是什么意思? foo: bar : baz 我明白 foo是一个目标,bar和 baz是先决条件,但为什么 bar 之间还有另一个冒号和 baz - 那个冒号是什么意思? 最佳答案 您想到
在 python 中我们可以说: if foo >> class Bar: def __init__(self, name): self.name = name
我想要一个正则表达式来匹配更广泛的表达式中除了几个特定选项之外的所有内容。 以下示例将匹配 test_foo.pl 或 test_bar.pl 或 test_baz.pl: /test_(foo|ba
这个问题已经有答案了: How can I find all placeholders for str.format in a python string using a regex? [duplic
我需要创建一个 JavaScript RegExp 对象,如果被测试的字符串不包含“foo”且不包含“bar”且不包含“baz”,该对象将返回 true。 这是一般的想法...我有一个很大的结果集。我
我想提供一个可以覆盖的默认值。我知道我可以使用三元,如下所示: (def foo (if (not (nil? bar)) bar baz)) 但在 Clojure 中肯定有一种更惯用的方式来表示“使
我正在阅读 dispatch 的代码,并遇到了这个 file ,其中,它说: object Elem extends (Res => scala.xml.Elem) { def apply(res
一个简单的问题:如果我有这样一行: int foo::bar::baz() {... 这是如何解释的? baz() 是函数名,但是“foo”是一个类还是一个命名空间? “bar”是类还是子类还是什么?
如何在 PHP5 类中创建链接对象?示例: $myclass->foo->bar->baz(); $this->foo->bar->baz(); Not: $myclass->foo()->bar()
这是我正在尝试做的一个精简的例子。 #!/usr/bin/env bash set -x echo "$@" 调用它 bash script -vv --foo='bar baz' 产量 + echo
我想知道 e 之间的这种光学不匹配是否有充分的理由。 G。模式匹配,它使用一个简单的 case foo => 表示不应采取任何行动。 有这样的东西不是很合理吗 import foo.bar.{Baz
我不喜欢附加到 ConcurrentDictionary 的方法。 AddOrUpdate 需要一个 func,而 GetOrAdd 在您只是寻找键以获取值时添加。所以我想像普通字典一样使用它(为了安
是否有模块能够做到这一点,还是我应该自己写一些东西? 最佳答案 这是怎么回事: >>> os.path.normpath("/bar/foo/baz/../..") "/bar" 关于python -
我不确定它到底叫什么,但我想知道如何创建一个可以在一次调用中调用多个方法的类。例如,使用一个 android 类,但这并不重要,您可以一次调用该类的所有方法: AlertDialog.Builder(
我是一名优秀的程序员,十分优秀!