typedef改变了含义
typedef changes meaning
当我用g++
编译以下代码段时
template<class T>
class A
{};
template<class T>
class B
{
public:
typedef A<T> A;
};
编译器告诉我
error: declaration of ‘typedef class A<T> B<T>::A’
error: changes meaning of ‘A’ from ‘class A<T>’
另一方面,如果我将typedef
更改为
typedef ::A<T> A;
用CCD_ 3编译一切都很好。Clang++3.1不管怎样都不在乎。
为什么会发生这种情况?第二种行为标准是什么?
g++正确且符合标准。来自[3.3.7/1]:
S类中使用的名称N应在其上下文以及在S.No的完整范围内重新评估时违反此规则需要进行诊断。
在typedef之前,A
引用::A
,但是通过使用typedef,现在可以使A
引用被禁止的typedef。然而,由于no diagnostic is required
,clang也是符合标准的。
日本政府的评论解释了这一规定的原因。对您的代码进行以下更改:
template<class T>
class A
{};
template<class T>
class B
{
public:
A a; // <-- What "A" is this referring to?
typedef A<T> A;
};
由于类作用域的工作方式,A a;
变得不明确。
我将添加到Jesse关于GCC在编译中看似特殊的行为的回答中:
typedef A<T> A;
与
typedef ::A<T> A;
这也适用于使用以下形式的语句:
using A = A<T>;
using A = ::A<T>;
GCC中似乎发生的事情是,在编译声明B::A的typedef/using语句期间,符号B::A在using语句本身中成为有效的候选者。即,当说using A = A<T>;
或typedef A<T> A;
时,GCC认为::A
和B::A
都是A<T>
的有效候选者。
这似乎是一种奇怪的行为,因为正如你的问题所暗示的,你不希望新的别名A成为typedef本身中的有效候选者,但正如Jesse的回答所说,类中声明的任何东西都会对类中的其他所有东西可见,在这种情况下,显然甚至是声明本身。这种类型的行为可以通过这种方式实现,以允许递归类型定义。
您发现的解决方案是为GCC精确指定您在typedef中引用的A,然后它就不再抱怨了。
相关文章:
- C++:TypeDef使用元组
- 变量没有改变?通过向量的函数调用
- 有没有一种方法可以通过"typedef"为重新定义的基本类型定义特征和强制转换运算符
- 为什么在使用typedef时类推导指南会失败
- 如何改变c++应用程序的视觉效果
- C++在不同线程中改变向量
- 如何访问和改变存储在矢量C++中的对象
- 尝试根据类中 typedef 的存在来专门化模板函数
- 如何重新定义MPI_FLOAT,MPI_DOUBLE以 typedef 的方式
- 在C++行尾写一个分号或多个分号是否会改变任何内容
- typedef 枚举和枚举类有什么区别?
- 在类模板中使用 typedef 时出错
- 为什么字符串的 move() 会改变内存中底层数据的位置?
- 模板类中的 typedef 语句
- 为什么 c++ 动态数组的大小没有改变?
- 在 typedef 内部使用 const 关键字和在 typedef 外部使用 const 关键字之间有区别吗?
- 如何将成员函数作为回调参数传递给需要"typedef-ed"自由函数指针的函数?
- 为什么提升图库的 read_graphviz() 函数会改变节点的索引
- typedef改变了含义
- Typedef改变行为导致错误和警告