c++ - 具有从属限定标识的类成员 using-declaration 是否应该是从属名称?

标签 c++ templates language-lawyer using-declaration dependent-name

C++11 标准草案 N3337 在 [namespace.udecl] 中声明

A using-declaration introduces a name into the declarative region in which the using-declaration appears.

Every using-declaration is a declaration and a member-declaration and so can be used in a class definition.

In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined.

这通常用于在派生类中公开基类中的 protected typedef,如下例所示,它在最新版本的 Clang 中成功编译:

struct A
{
protected:
    typedef int Type;
};

struct B : A
{
    using A::Type;
};

B::Type x;

using 声明可以引用模板类。这编译:

struct A
{
protected:
    template<typename T>
    struct Type
    {
    };
};

struct B : A
{
    using A::Type;
};

B::Type<int> x;

也可以引用依赖基类中的模板。以下编译成功(注释了 typedef。)

template<typename T>
struct A
{
protected:
    template<typename U>
    struct Type
    {
    };
};


template<typename T>
struct B : A<T>
{
    using /* typename */ A<T>::Type; // A<T> is dependent, typename required?
    // typedef Type<int> IntType; // error: unknown type name 'Type'
};

B<int>::Type<int> x;

取消注释 typename实例化时导致错误 B<int> : “错误:'typename' 关键字用于非类型”。

取消注释 typedef 会导致解析时出错 B在第一次实例化之前。我猜这是因为编译器不处理 Type作为依赖类型名称。

最后一段[namespace.udecl]建议 using-declarations 可以指定从属名称,并且 typename必须使用关键字来消除引入名称的进一步用法的歧义:

If a using-declaration uses the keyword typename and specifies a dependent name (14.6.2), the name introduced by the using-declaration is treated as a typedef-name

我对 [temp.dep] 的阅读建议 A<T>::Type是从属名称。从逻辑上讲,using 声明引入的名称也应该是依赖的,但是 [temp.dep]没有明确提及依赖使用声明的情况。我错过了什么吗?

最佳答案

问题是 Type 不是一个类,而是一个类模板。您可以执行以下操作(这样您就可以告诉编译器 TypeB 范围内的类模板):

template<typename T>
struct B : A<T>
{
    using A<T>::Type;
    typedef typename B::template Type<int> IntType;
};

实际上,在您的第二个示例中,为了为 IntType 编写 typedef,您必须执行相同的操作。

关于c++ - 具有从属限定标识的类成员 using-declaration 是否应该是从属名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27158750/

相关文章:

c++ - Fortran 和 C++ : Linking error in Visual Studio

c++ - 在 VS2013 中初始化 std::discrete_distribution

c++ - opencv matchTemplate 在计算机之间给出不一致的结果

c++ - 模板化友元声明在 g++ 5.4.0 下不起作用——编译器错误或错误代码?

c++ - header 中的类模板

c++ - 64 位机器上 vptr 的大小**必须**是 64 位吗?

c++ - reinterpret_cast 创建一个简单的默认构造对象

c++ - C+ +'s "inline"- 对 GCC 和 Clang/LLVM 的提示有多强?

c++ - 如何禁用某些模板类型的类成员函数

c - 使用 fgetc 时是否可能将 EOF 与正常字节值混淆?