Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/139.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 是";使用typename";编译器未实现的指令?_C++_Using_Nested Class_Typename - Fatal编程技术网

C++ 是";使用typename";编译器未实现的指令?

C++ 是";使用typename";编译器未实现的指令?,c++,using,nested-class,typename,C++,Using,Nested Class,Typename,我有一些代码如下所示: namespace myLibrary { class A { public: struct Nested { ... }; ... }; } using myLibrary::A::Nested; 在代码的其他部分中,我需要访问A。因为我喜欢可读代码,所以我也喜欢using指令: using myLibrary::A; ... A a; 现在,

我有一些代码如下所示:

namespace myLibrary
{
    class A
    {
    public:
        struct Nested
        {
            ...
        };

        ...
    };
}
using myLibrary::A::Nested;
在代码的其他部分中,我需要访问A。因为我喜欢可读代码,所以我也喜欢using指令:

using myLibrary::A;
...
A a;
现在,在某个时候,我还需要访问嵌套类,因此我想编写如下内容:

namespace myLibrary
{
    class A
    {
    public:
        struct Nested
        {
            ...
        };

        ...
    };
}
using myLibrary::A::Nested;
显然,编译器无法知道这是一个嵌套类而不是类成员,因此给了我一个错误:

error : using declaration can not refer to class member
我不明白的是,为什么这不能解决问题:

using typename myLibrary::A::Nested;
编译器仍然给我完全相同的错误

幸运的是,我有其他选择:

// Using a typedef
typedef myLibrary::A::Nested Nested;

// Using the new C++11 syntax for type aliasing
using Nested = myLibrary::A::Nested;
但是我想理解为什么using-typename指令不起作用。它不是我想的那样吗?或者它不是由编译器实现的?如果是后者,有什么原因吗?

没有“使用typename指令”。有使用指令和使用声明

您没有使用任何using指令,而且它们在任何情况下都与问题无关(它们命名名称空间,并且不能使用typename关键字)

当使用声明碰巧出现在类模板中,并且碰巧出现在名称相关类型中时,它们必须使用
typename
关键字,就像模板中碰巧出现并命名相关类型的任何其他内容一样

例如:

template <typename A, typename R>
class Functor : public std::unary_function<A, R>
{
    using typename std::unary_function<A, R>::result_type;
    using typename std::unary_function<A, R>::argument_type;
 public:
    result_type operator() (argument_type) {}
};
模板
类函子:公共std::一元函数
{
使用typename std::一元函数::结果类型;
使用typename std::一元函数::参数类型;
公众:
结果类型运算符()(参数类型){}
};
在您的情况下,名称空间声明似乎不是类模板主体的一部分,实际上它似乎在名称空间范围内,在这种情况下,试图命名类成员(不管它是类型还是函数或其他什么)违反了
7.3.3[namespace.udecl]/8

类成员的使用声明应为成员声明


由于编译器正确诊断为“错误:使用声明不能引用类成员”

A
使用
声明引用命名空间成员
A
只能出现在命名空间或本地范围


使用
声明引用类成员
嵌套的
只能出现在类作用域中(与成员声明一起),在从
嵌套派生的类中。事实上,这种使用的
声明在语法上被认为是成员声明。它们用于调整访问限定,并(使用
typename
)允许使用类型相关基的成员而无需限定。这些都是特定的用例,所以成员
使用
声明有点专业化

嵌套类是其封闭类的成员。通常应避免使用类附件作为名称空间的替代品。元编程为该规则提供了一些例外情况,但在这些情况下,您仍然不会使用
使用
声明,至少是命名空间范围,因为命名空间无法模板化。从一个空的元编程类继承是可行的,但请注意意大利面条


使用
指令的
是另一个beast。它看起来像是
使用名称空间
,并将一个名称空间链接到另一个名称空间,作为名称查找的备用路径。

据我所知,它只针对名称空间成员,而不是类成员:@DiscoStu:可能,但在这种情况下,为什么要引入“typename”关键字?它似乎应该与using一起工作:您尝试使用using声明的上下文是什么?
Nested
必须始终称为
A::Nested
,除非它位于
A
的成员变量或函数中。如果您的代码似乎要求在不使用
A::
的情况下谈论
Nested
,这表明不将其作为嵌套类可能是更好的设计。@MattMcNabb:如果您想知道,A是一个描述机器人关节的类,Nested是关节角度限制的结构。对我来说,将其嵌套是有意义的,尽管有时我必须从外部访问它。非常感谢!很抱歉称之为“指令”。我认为区别在于“使用声明”是类主体中的声明,“使用指令”是其他声明。