c++ - 需要帮助理解这篇关于模板的文章

标签 c++ templates

我正在阅读这篇文章 page ,所以让我展示代码:

template <class T> class D: typename C<T>::Base { //#1 error
    D(): typename C<T>::Base(typename C<T>::Base(0)) { } //#2 error, #3 correct
    typename C<T> f() { //#4 error
        typename C<T>::A* p; //#5 correct
        A<T>::B * n;
    }
};
class Q{
    typename C<long>::A * p; // #6 error
}
template <class T, class U> class R{
    typename C<long>::A * p; // #7 optional
}

#3 是正确的,但我试图理解作者试图传达的意思。他说:

typename #3: correct. Here, typename is used for disambiguating the type of a parameter. Without typename, the expression C::Base(0) would be treated as a call to a function called Base. With the typename prefix, C::Base(0) creates a temporary object of type C::Base initialized with the argument 0.

此外,如果您看到作者所说的那部分上方一点:

The typename keyword must prefix a dependent name when that name satisfies the following three rules:

1.It appears inside a template

2.It's qualified // i am unable to understand this line at all in conjunction with starting para of this quote

3.It isn’t used in a base class specification or a member initialization list.

我根本无法理解这一行(上面的#2)以及这句话的开头段落。你能解释一下作者的意思吗?

最佳答案

“合格”的意思是不在同一个范围内,而是当前的一个子范围,也依赖于一个模板。例如,

template <class T> struct C {
    typedef int b;
}

b 在另一个模板中引用时是一个限定的 id,例如

template<typename T> struct M {
    typename C<T>::b bb;
}

标准(§14.6.3)的相关引用:

A qualified-id that refers to a type and in which the nested-name-specifier depends on a template-parameter (14.6.2) shall be prefixed by the keyword typename to indicate that the qualified-id denotes a type, forming an elaborated-type-specifier (7.1.5.3).

和§14.6.2:

A name used in a template declaration or definition and that is dependent on a template-parameter is
assumed not to name a type unless the applicable name lookup finds a type name or the name is qualified
by the keyword typename. [Example:
    // no B declared here
    class X;
    template<class T> class Y {
        class Z; // forward declaration of member class
        void f() {
            X* a1; // declare pointer to X
            T* a2; // declare pointer to T
            Y* a3; // declare pointer to Y<T>
            Z* a4; // declare pointer to Z
            typedef typename T::A TA;
            TA* a5; // declare pointer to T’s A
            typename T::A* a6; // declare pointer to T’s A
            T::A* a7; // T::A is not a type name:
            // multiply T::A by a7; ill-formed,
            // no visible declaration of a7
            B* a8; // B is not a type name:
            // multiply B by a8; ill-formed,
            // no visible declarations of B and a8
        }
    };
—end example]

和§14.6.7:

Within the definition of a class template or within the definition of a member of a class template, the keyword
typename is not required when referring to the unqualified name of a previously declared member
of the class template that declares a type. The keyword typename shall always be specified when the
member is referred to using a qualified name, even if the qualifier is simply the class template name.
[Example:
    template<class T> struct A {
        typedef int B;
        A::B b; // ill-formed: typename required before A::B
        void f(A<T>::B); // ill-formed: typename required before A<T>::B
        typename A::B g(); // OK
    };

The keyword typename is required whether the qualified name is A or A<T> because A or A<T> are synonyms
within a class template with the parameter list <T>. ]

关于c++ - 需要帮助理解这篇关于模板的文章,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7286985/

相关文章:

html - 电子邮件模板管理器工具

c++ - 有没有办法使用模板来避免缩小转换?

java - 扩展 Axis 代码生成模块

c++ - 用C++做了一个递归函数。现在要求制作一个 "tail-recursion"函数

c++ - 为什么 foo->bar->foobar 被认为是不好的风格?以及如何在不添加代码的情况下避免?

C++ 计数时间克服 clock_t 的 72 分钟范围

c++ - 是否可以使用 C++ 元编程收集一个特定模板的所有显式实例化类型?

c++ - 我的程序返回错误 "vector subscript out of range."

c++ - 磁盘结构元素opencv vs Matlab

javascript - 正则表达式匹配用大括号包裹的单词