简体   繁体   English

C ++类函数返回类型定义,返回一个类

[英]C++ class function return type definition, return a class

I have a vector class look like this: 我有一个矢量类看起来像这样:

class Vector3
{

 public:
   Vector3(){m_x = m_y = m_z = 0.0f;}
   Vector3(const float & i_x, const float & i_y, const float & i_z):
     m_x(i_x), 
     m_y(i_y),
     m_z(i_z)
     {}

   Vector3 operator+(const Vector3 & i_other);
private:
   float m_x;
   float m_y;
   float m_z;
};

Vector3::Vector3 Vector3::operator+(const Vector3 & i_other)
{
   float tx = m_x + i_other.m_x;
   float ty = m_y + i_other.m_y;
   float tz = m_z + i_other.m_z;
   return Vector3(tx, ty, tz);
}

Obviously, the Vector3::operator+ definition synax is wrong because the return type is Vector3::Vector3 , not Vector3 . 显然, Vector3::operator+定义synax是错误的,因为返回类型是Vector3::Vector3 ,而不是Vector3 Vector3::Vector3 means there is a namespace Vector3 , and inside the name space there is a class Vector3 . Vector3::Vector3意味着有一个命名空间Vector3 ,并且在名称空间内有一个Vector3类。 But I only have a class Vector3 , no namespace here. 但是我只有一个Vector3类,这里没有名称空间。

My question is, in Ubuntu 12.04, the syntax above can not be compiled (Ubuntu's g++ compiler is [gcc version 4.6.3]). 我的问题是,在Ubuntu 12.04中,无法编译以上语法(Ubuntu的g ++编译器为[gcc版本4.6.3])。 However, in Mac, g++ can compile the code(Mac's g++ compiler is [gcc version 4.2.1]). 但是,在Mac中,g ++可以编译代码(Mac的g ++编译器为[gcc版本4.2.1])。 Also, I test this syntax in a Red Hat linux machine, it also works (g++ version is [gcc version 4.4.6]) 另外,我在Red Hat linux机器上测试了这种语法,它也可以工作(g ++版本是[gcc版本4.4.6])

So, is it different version of gcc have different compile principle? 那么,不同版本的gcc是否具有不同的编译原理? Or, my g++ in Ubuntu broke? 或者,我在Ubuntu中的g ++坏了吗?

The older compiler is incorrect. 旧的编译器不正确。 Little surprise there. 一点也不奇怪。

It is probably parsing Vector3::Vector3 as an injected-type-name. 可能是将Vector3::Vector3解析为注入类型名称。 Inside the scope of class Vector3 { } , the identifier Vector3 refers to the class, not the constructor (except when you're declaring the constructor, of course). class Vector3 { }的范围内,标识符Vector3引用该类,而不是构造函数(当然,在声明构造函数时除外)。 And at first glance, you might think it means the same thing in a return type, because §3.4/3 (I'm using the C++11 standard here) says 乍一看,您可能会认为它在返回类型中含义相同,因为§3.4/ 3(我在这里使用的是C ++ 11标准)说

The injected-class-name of a class (Clause 9) is also considered to be a member of that class for the purposes of name hiding and lookup. 出于名称隐藏和查找的目的,一个类的注入类名(第9条)也被认为是该类的成员。

Digging deeper, in §3.4.3.1/2, 在第3.4.3.1/2节中深入探讨,

In a lookup in which the constructor is an acceptable lookup result and the nested-name-specifier nominates a class C: 在查找中,构造函数是可接受的查找结果,并且nested-name-specifier提名类C:

— if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (Clause 9) —如果在C中查询在nested-name-specifier后指定的名称是C的注入类名称(第9条)

the name is instead considered to name the constructor of class C. 该名称被认为是为类C的构造函数命名。

The context of starting a declaration with an injected-class-name happens to be the same as in defining a constructor outside class {} scope, a la 用注入的类名开始声明的上下文恰好与在class {}范围之外定义构造函数相同,例如

class Vector3 { … };

Vector3::Vector3(){m_x = m_y = m_z = 0.0f;}

The older GCC noticed that the declaration wasn't a constructor, then took a fallback path that did work. 较老的GCC注意到该声明不是构造函数,因此采用了有效的后备路径。 However that fallback was illegal because C++ specifies that in a context where the constructor could be the result of the lookup, it is the only valid lookup result. 但是,这种回退是非法的,因为C ++指定在构造函数可能是查找结果的上下文中,它是唯一有效的查找结果。

In all probability, some user took the time to file a bug, and a GCC developer took the time to diagnose this, fix it, and write a testcase. 很有可能,有些用户花了一些时间来提交错误,而GCC开发人员则花了一些时间来诊断,修复和编写测试用例。 Multiply across the number of trivialities in a complex language like C++, and you start to appreciate the effort put into your compiler. 用复杂的语言(例如C ++)乘以琐碎的次数,您就会开始欣赏编译器所做的工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM