使用不完整类型,引用vs指针无效

Abs*_*ion 5 c++ g++

下面的代码在Visual Studio和g ++中编译和工作:

class A;
A* getRef(void);
char (&func(...))[2];

int main() {
    bool isDefault = sizeof(func(getRef()))==2;
    std::cout << isDefault << std::endl; //prints 1
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

下一代码仍然在Studio中编译(并且可以工作),但g ++声明这是invalid use of incomplete type 'class A':

class A;
A& getRef(void); //the only change
char (&func(...))[2];

int main() {

    bool isDefault = sizeof(func(getRef()))==2; //g++ error here
    std::cout << isDefault << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是一个根本错误的代码,应该被编译器拒绝(如果是这样,为什么VS编译器不会产生任何警告)?或者在这个上下文中指针和引用之间是否存在一些我不知道的区别?

Che*_*Alf 4

修改后的代码的关键方面是对不完整类型的引用作为实际参数传递给省略号形式参数。

\n\n C++11 \xc2\xa75.2.2/7,关于省略号的参数: \n\n
\n

左值到右值 (4.1)、数组到指针 (4.2) 和\n 函数到指针 (4.3) 标准转换是对参数表达式执行的。具有(可能是 cv 限定的)类型的参数std::nullptr_t将转换为类型void*(4.10)。在这些转换之后,如果参数没有算术、枚举、指针、成员指针或类类型,则程序格式错误。

\n
\n\n

然后对于左值到右值的转换,我们发现

\n\n C++11 \xc2\xa74.1/1: \n\n
\n

非函数、非数组类型的左值 (3.10)可以T转换为纯右值。如果T是不完整类型,则需要此转换的程序格式错误。

\n
\n\n

当我读到它时,但这只是我的直觉解释,对Ttype 的泛左值的引用T,在这里是不完整的,会产生格式错误的代码。

\n