C++ 在类内任何点已知的类的成员

C++ 在类内任何点已知的类的成员,c++,C++,我一直认为,如果我在类内声明一个类的成员,则该成员在类的整个范围内都是已知的,即: class X { public: X(int a) :v_(a) {} private: int v_;//even though v_ is declared here I'm using it in ctor which is above this line }; 这对我来说很有意义 无论如何,这并不是因为我得到了一个错误,v\uu是未知的 class X { public:

我一直认为,如果我在类内声明一个类的成员,则该成员在类的整个范围内都是已知的,即:

 class X
{
public:
    X(int a) :v_(a)
    {}
private:
    int v_;//even though v_ is declared here I'm using it in ctor which is above this line
};
这对我来说很有意义

无论如何,这并不是因为我得到了一个错误,
v\uu
是未知的

class X
{
public:
    X(decltype(v_) a) :v_(a)//error on this line, compiler doesn't know v_
    {}
private:
    int v_;
};
我很高兴知道原因

我使用的是英特尔编译器v14 SP1


谢谢。

您的代码编译时发出叮当声


阅读C++11规范时,不允许在变量用作函数/构造函数参数后声明该变量。

在许多情况下,包含函数签名的类将在头文件中定义,但函数体将在cpp文件中定义。由于编译器在开始读取cpp文件时已经读取了头文件,因此通常不会出现此问题。但是,C++编译器确实没有向前看。 3.3.7类别范围

1以下规则描述了类中声明的名称的范围


1) 类中声明的名称的潜在作用域不仅包括以下声明性区域 名称的声明点,也是所有函数体、大括号或相等的非静态初始值设定项的声明点 数据成员和该类中的默认参数(包括嵌套类中的此类内容)

这意味着您可以在函数体、构造函数初始值设定项列表和默认参数中使用
v\uu
。不允许在参数声明中使用代码中使用的方式

例如,这将编译

class X
{
public:
    X(int a = decltype(v_)()) : v_(a)
    {}
private:
    int v_;
};

但不是您原始帖子中的第二个示例。

相反的形式有效:看起来像decltype的bug。您是否尝试将int v_uu移动到decltype@pm100在gcc 4.8.2中,在ctor修复错误之前,生成了相同的错误,并声明了
v_u
,但该错误在gcc 4.8.2中未编译。对不起,使用了gcc 4.10,但在clang中编译良好^^^^^我假设clang。您可以使用gccgodbolt测试大量编译器。在GCC 4.9上,它没有编译..*我假设clang是正确的,不管怎样我正在阅读规范,以确定哪个编译器是正确的,哪个编译器是正确的。这没什么好遗憾的,只是提到它在这个版本上没有编译。我不知道你所说的“向前看”到底是什么意思,但整个类必须在函数体和构造函数初始值设定项列表中被视为一个完全定义的类型,而不管它们定义在何处。因此,为了达到这个目的,编译器需要向前看。我的意思是,应该首先定义成员,然后才使用。在某些上下文中,语言没有这样的要求。例如,在成员函数体中,成员可以在定义之前使用。Beat me:)。我几乎是复制粘贴了与编辑相同的语句到我的答案:)干得好。工作示例是wellcome extra:您的答案很快就会被接受;)当v_uu在ctor之前声明时,是否允许使用其他方法?“不仅是名称声明点后面的声明性区域”,因此至少该区域是有效的(当v_u在之前声明时也是如此)。您应该注意,如果稍后有人触摸您的代码(例如,通过移动成员来执行“缓存优化”,这可能会使您的代码无法编译(因此请在变量“Optimizers请勿移动此成员”或类似的内容旁边添加注释:D)