- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我有一些代码,就这个问题而言,归结为
template<typename T>
class TemplateClass : public T {
public:
void method() {}
template<typename U>
static void static_method(U u) { u.TemplateClass::method(); }
};
class EmptyClass {};
int main() {
TemplateClass<TemplateClass<EmptyClass> > c;
TemplateClass<EmptyClass>::static_method(c);
}
我尝试使用两个编译器的多个版本来编译它。 GCC 4.2、4.4、4.6 毫无怨言地接受它。截至 11 月 14 日的 Clang 2.9 和 SVN 主干拒绝它并显示以下错误消息:
example.cc:6:38: error: lookup of 'TemplateClass' in member access expression is
ambiguous
static void static_method(U u) { u.TemplateClass::method(); }
^
example.cc:13:3: note: in instantiation of function template specialization
'TemplateClass<EmptyClass>::static_method<TemplateClass<TemplateClass<EmptyClass>
> >' requested here
TemplateClass<EmptyClass>::static_method(c);
^
example.cc:2:7: note: lookup in the object type
'TemplateClass<TemplateClass<EmptyClass> >' refers here
class TemplateClass : public T {
^
example.cc:2:7: note: lookup from the current scope refers here
1 error generated.
哪一个是错的?我可以通过更改来解决 Clang 问题
static void static_method(U u) { u.TemplateClass::method(); }
到
static void static_method(U u) { u.TemplateClass<T>::method(); }
但我希望自己能够理解何时可以省略模板参数。
编辑:我曾认为歧义存在于 TemplateClass
的两个实例之间。以下代码使用 GCC 和 Clang 编译,质疑该假设:
class E {};
template<typename T>
class A : public T {
public:
void method() {}
};
int main() {
A<A<E> > a;
a.A::method();
}
最佳答案
我相信 clang 正确地拒绝了这个代码。
clang 发现的歧义可以用一个不太复杂的例子来重现:
template<typename T>
class TemplateClass {
public:
void method() {}
template<typename U>
static void static_method(U u) { u.TemplateClass::method(); }
};
struct A {};
struct B {};
int main() {
TemplateClass<A> c;
TemplateClass<B>::static_method(c);
}
这里省略了模板中的继承,并使用了两个独立的类进行实例化。 clang 产生的错误还是一样。
首先,在TemplateClass<T>
的范围内姓名TemplateClass
指TemplateClass<T>
,由于类名注入(inject)。这就是静态方法可以使用TemplateClass::method
的原因。而不是更明确的 TemplateClass<T>::method
.
用于解释 u.TemplateClass::method
的名称查找静态方法中的定义在 C++11 和 C++98 标准的“3.4.5 类成员访问[base.lookup.classref]”中。
相关部分是3.4.5/4:
If the id-expression in a class member access is a qualified-id of the form
class-name-or-namespace-name::...
[...]
这里就是这种情况。 id-expression 是 .
右侧的部分在我们的例子中,这是限定名称 TemplateClass::method
.
[...]
the class-name-or-namespace-name following the.
or->
operator is looked up both in the context of the entire postfix-expression and in the scope of the class of the object expression.
“整个后缀表达式的作用域”是静态函数的主体,在这个静态函数中TemplateClass
指TemplateClass<B>
,因为该函数是该类的成员(我们称为 TemplateClass<B>::static_method
)。
所以在这个范围内,名称指的是 TemplateClass<B>
.
“对象表达式”是 .
的左边部分, 在我们的例子中 c
. c
的类(class)是 TemplateClass<A>
在这个类的范围内,TemplateClass
指TemplateClass<A>
.
因此,根据用于查找的范围,名称指的是不同的实体。
标准现在说:
If the name is found in both contexts, the class-name-or-namespace-name shall refer to the same entity.
在我们的程序中并非如此。程序格式不正确,需要编译器给出诊断信息。
如果替换 B
,歧义保持不变与 TemplateClass<A>
,如问题中所用。
关于c++ - 不明确的成员访问表达式 : is Clang rejecting valid code?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8100492/
我在 linux 上工作。我对windows没有太多想法。 windows中文件的权限是如何组织的?我们在unix中是否有像chmod这样的api来更改权限? 最佳答案 对于 Windows,有一个名
应用程序编程接口(interface) (API) 是一组用于访问基于 Web 的软件应用程序的编程指令和标准。 如果出现 ,有人可以向我解释一下吗?谷歌地图 或 优酷 这是API哪个是softwar
我有两个应用程序,A 和 B,它们使用 android 库 C。B 有一个服务 A 想通过 C 使用,例如 在我的库中有一个类试图将它绑定(bind)到服务,
我正在正常或安全模式下启动相机应用程序,具体取决于使用我的应用程序执行的手势,但一旦用户选择应用程序并点击始终,则没有选项可以更改默认值,即使是从 Android 的设置菜单中也是如此. camera
我有一个数据集,本质上是一个稀疏二进制矩阵,表示两个集合的元素之间的关系。例如,让第一组是人(用他们的名字表示),例如像这样的东西: people = set(['john','jane','mike
何为pythonic? pythonic如果翻译成中文的话就是很python。很+名词结构的用法在中国不少,比如:很娘,很国足,很CCTV等等。 我的理解为,很+名词表达了一种特殊和强调的意味。
某些 Prolog 目标的确定性成功问题已经一次又一次地出现在 - 至少 - 以下问题: Reification of term equality/inequality Intersection an
我指的是 DateTime.TryParse(string s, out DateTime result) 重载,它尝试从字符串中解析 DateTime - 没有特定的格式正在指定。 我可以从http
2020 年 04 月 10 日,《中共中央国务院关于构建更加完善的要素市场化配置体制机制的意见》正式公布,将数据确立为五大生产要素(土地、资本、劳动力以及技术)之
有人可以解释一下 NSNotification 的 addObserver 函数中 notificationSender 的用途吗? 这是 Apple 文档的解释: notificationSende
我是一名优秀的程序员,十分优秀!