wil*_*llj 6 c++ templates language-lawyer
在下面的示例中,A有一个成员typedef Instantiate导致实例化B<A>.
template<typename T>
struct B
{
typedef typename T::Before Before; // ok
typedef typename T::After After; // error: no type named 'After' in 'A<int>'
};
template<typename T>
struct A
{
typedef int Before;
typedef typename B<A>::After Instantiate;
typedef int After;
};
template struct A<int>; // instantiate A<int>
Run Code Online (Sandbox Code Playgroud)
我尝试过的所有编译器都报告说,虽然A::Before可见但A::After并非如此.这种行为是否符合标准?如果是这样,标准在哪里指定A在实例化期间哪些名称应该可见B<A>?
如果依赖名称"在模板实例化时查找",那么在由模板参数限定的名称场景中,这意味着什么T::After?
编辑:请注意,当A不是模板时,会发生相同的行为:
template<typename T>
struct B
{
typedef typename T::Before Before; // ok
typedef typename T::After After; // error: no type named 'After' in 'A'
};
struct A
{
typedef int Before;
typedef B<A>::After Instantiate;
typedef int After;
};
Run Code Online (Sandbox Code Playgroud)
..和G ++接受以下内容,但Clang没有:
template<typename T>
struct B
{
static const int value = 0;
static const int i = T::value; // clang error: not a constant expression
};
struct A
{
static const int value = B<A>::value;
};
Run Code Online (Sandbox Code Playgroud)
编辑:经过一些C++ 03标准的阅读:
[temp.dep.type]如果类型是模板参数,则该类型是相关的
因此T是依赖的.
[temp.res]在查找模板定义中使用的名称声明时,通常的查找规则用于非依赖名称.依赖于模板参数的名称查找被推迟,直到知道实际模板参数.
因此,查询T::After被推迟,直到T知道参数为止.
[temp.inst]除非已显式实例化类模板特化,否则在需要完全定义的对象类型的上下文中引用特化时,将隐式实例化类模板特化.
因此声明A<int>::Instantiate需要实例化B<A>(因为它在嵌套名称说明符中使用.)
A<int>::After在声明时是不可见的A<int>::Instantiate,因此编译器的行为是有意义的 - 但我没有在C++ 03中看到任何明确描述此行为的内容.最接近的是这个有点模糊的段落:
[temp.dep.res]在解析依赖名称时,会考虑以下来源的名称:
- 在模板定义点可见的声明.
typename T::Before规范中没有明确说明是否有效。它是缺陷报告的主题(因为可以非常合理地阅读该标准来禁止它):http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287。
是否typename T::After无效也可以很合理地被规范解读为正确,实际上它很有道理(前面提到的 DR 仍然保持它的格式错误)。因为您有一个类的实例化A<Foo>,它在尚未声明A<Bar>成员的期间引用了另一个类,并且这会引用回. 在非模板的情况下,这也是格式不正确的(尝试暂时“忘记”您正在处理模板:当然,查找是在模板完全解析之后完成的,而不是在它的特定实例化之后完成的已完全创建。并且它的实例化实际上将进行引用!)。BazA<Foo>::BarB<A>::AfterA
struct A {
typedef int Foo;
typedef A::Foo Bar; // valid
typedef A::Baz Lulz; // *not* valid
typedef int Baz;
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
705 次 |
| 最近记录: |