gpt4 book ai didi

c++ - 实例化模板时,其不完整参数类型的成员是否应该可见?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:31:40 27 4
gpt4 key购买 nike

在下面的例子中,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>

我试过的所有编译器都报告说,而 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;
};

.. 和 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;
};

编辑:阅读 C++03 标准后:

[temp.dep.type] A type is dependent if it is a template parameter

因此T是依赖的。

[temp.res] When looking for the declaration of a name used in a template definition, the usual lookup rules are used for nondependent names. The lookup of names dependent on the template parameters is postponed until the actual template argument is known.

查找T::After因此推迟到 T 的参数众所周知。

[temp.inst] Unless a class template specialization has been explicitly instantiated ... the class template specialization is implicitly instantiated when the specialization is referenced in a context that requires a completely-defined object type.

因此 A<int>::Instantiate 的声明需要实例化 B<A> (因为它用在嵌套名称说明符中。)

A<int>::AfterA<int>::Instantiate 的声明点不可见,所以编译器的行为是有道理的——但我在 C++03 中没有看到任何明确描述这种行为的内容。最接近的是这个有点模糊的段落:

[temp.dep.res] In resolving dependent names, names from the following sources are considered:

— Declarations that are visible at the point of definition of the template.

最佳答案

是否typename T::Before is valid 规范没有明确说明。它是缺陷报告的主题(因为可以非常合理地阅读标准以禁止它):http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#287 .

是否typename T::After is invalid 也可以非常合理地被规范解读为 true,实际上它很有道理(并且前面提到的 DR 仍然保持它的格式错误)。因为你有一个类的实例化 A<Foo> ,它引用了另一个类 A<Bar>在成员(member)期间Baz尚未宣布,这使对 A<Foo>::Bar 的引用.这在非模板的情况下也是错误的(尝试暂时“忘记”您正在处理模板:B<A>::After 的查找肯定是在 A 之后完成的。模板已完全解析,但不是在它的特定实例化完全创建之后。它的实例化实际上将进行引用!)。

struct A {
typedef int Foo;
typedef A::Foo Bar; // valid
typedef A::Baz Lulz; // *not* valid
typedef int Baz;
};

关于c++ - 实例化模板时,其不完整参数类型的成员是否应该可见?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17478621/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com