Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/163.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++ C+中的多个声明+;_C++_C++11_Language Lawyer - Fatal编程技术网

C++ C+中的多个声明+;

C++ C+中的多个声明+;,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,在[basic.scope.declarative]p4中,我们读到 给定单个声明区域中的一组声明,每个声明指定相同的非限定名称,-(4.1),它们都应指向同一实体 天真的解读可能意味着以下代码可能是有效的,因为“两个声明都引用同一个实体”: 然后,人们可能会记住一个定义规则[basic.def.odr]p1。上述推理可能只适用于声明,而不适用于定义。区别在[basic.def]p2中有详细说明。例如,以下代码肯定是有效的: extern int x; extern int x; [basic

在[basic.scope.declarative]p4中,我们读到

给定单个声明区域中的一组声明,每个声明指定相同的非限定名称,-(4.1),它们都应指向同一实体

天真的解读可能意味着以下代码可能是有效的,因为“两个声明都引用同一个实体”:

然后,人们可能会记住一个定义规则[basic.def.odr]p1。上述推理可能只适用于声明,而不适用于定义。区别在[basic.def]p2中有详细说明。例如,以下代码肯定是有效的:

extern int x;
extern int x;
[basic.def]p2中的最后一个示例表明以下代码应该是有效的,但它不会编译(使用MSVC2015)

问题出在哪里?


错误消息是

“B::y”的使用声明不能与“B::y”的现有使用声明共存


[namespace.udecl]p10中的示例与您的示例完全相同:

struct B {
   int i;
};
struct X : B {
   using B::i;
   using B::i; // error: double member declaration
};
错误由[class.mem]p1备份:

构件规范中不得对构件进行两次声明, 除非可以声明嵌套类或成员类模板 然后再定义,除了枚举可以 使用不透明枚举声明引入,然后使用重新声明 枚举说明符

所以你走对了方向。多个声明是可以的,只要它们不违反其他规则(例如一个定义、成员规范等)

例如,以下各项可以:

struct X;
struct X;
或者更复杂的例子:

struct X 
{
    struct A;
    struct A
    {
       int y;
    };
}; 

struct X;
struct X::A;

您几乎通过引用namespace.udecl/10回答了自己的问题。下面的示例(N3936)显示了一个位置,其中允许使用多个等效的
声明:

namespace A {
    int i;
}
namespace A1 {
    using A::i;
    using A::i; // OK: double declaration
}
void f() {
    using A::i;
    using A::i; // error: double declaration
}
struct B {
    int i;
};
struct X : B {
    using B::i;
    using B::i; // error: double member declaration
};
使用
的多个——也允许在命名空间和块范围内对函数进行声明。至于为什么它们不允许用于块范围内的变量(对象),我不知道。由于两个原因,可能不允许使用多个等效成员声明:

  • 初始化顺序错误的可能性很大
  • 从历史上看,这是不必要的,因为在同一个类中定义了内联“see”成员的方法体(在C++11中引入了
    decltype
    ,这个原因不再是确定的)

您忽略了一个事实,即您的第一次报价并不意味着任何此类声明都是合法的;只是如果他们不遵守,那么他们就是非法的。由于其他原因,它们可能是非法的(在本例中是非法的)。换句话说,“shall”的意思是。我刚刚阅读了[namespace.udecl]第10页:“using声明是一种声明,因此可以在允许(并且仅在)多个声明的地方重复使用。”我搜索了“multiple declarations”一词,找到了3个实例,其中没有一个说明这些地方可能在哪里。我也没有“申报两次”的运气。所以,我猜这些位置在结构、类、枚举和联合中。其他地方似乎都可以。
struct X 
{
    struct A;
    struct A
    {
       int y;
    };
}; 

struct X;
struct X::A;
namespace A {
    int i;
}
namespace A1 {
    using A::i;
    using A::i; // OK: double declaration
}
void f() {
    using A::i;
    using A::i; // error: double declaration
}
struct B {
    int i;
};
struct X : B {
    using B::i;
    using B::i; // error: double member declaration
};