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

标签 c++ syntax g++

我有一个像这样的 vector 类:

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);
}

显然,Vector3::operator+ 定义语法是错误的,因为返回类型是Vector3::Vector3,而不是Vector3Vector3::Vector3表示有一个命名空间Vector3,在命名空间里面有一个类Vector3。但是我只有一个类Vector3,这里没有命名空间。

我的问题是,在Ubuntu 12.04中,上面的语法无法编译(Ubuntu的g++编译器是[gcc version 4.6.3])。但是,在Mac中,g++可以编译代码(Mac的g++编译器是[gcc version 4.2.1])。另外,我在 Red Hat linux 机器上测试了这个语法,它也有效(g++ 版本是 [gcc 版本 4.4.6])

那么,是不是不同版本的gcc编译原理不同?或者,我在 Ubuntu 中的 g++ 坏了?

最佳答案

旧的编译器不正确。没什么惊喜。

它可能将 Vector3::Vector3 解析为注入(inject)类型名称。在 class Vector3 { } 的范围内,标识符 Vector3 指的是类,而不是构造函数(当然,声明构造函数时除外)。乍一看,您可能认为它在返回类型中意味着相同的东西,因为 §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.

深入挖掘,在 §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:

— if the name specified after the nested-name-specifier, when looked up in C, is the injected-class-name of C (Clause 9)

the name is instead considered to name the constructor of class C.

以注入(inject)类名开始声明的上下文恰好与在 class {} 范围之外定义构造函数时相同,a la

class Vector3 { … };

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

较旧的 GCC 注意到声明不是构造函数,然后采用了可行的后备路径。然而,这种回退是非法的,因为 C++ 指定在构造函数可能是查找结果的上下文中,它是唯一有效的查找结果。

很可能,某些用户花时间提交错误,而 GCC 开发人员花时间诊断、修复它并编写测试用例。乘以 C++ 等复杂语言中琐碎的数量,您就会开始欣赏编译器所付出的努力。

关于C++类函数返回类型定义,返回一个类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14492878/

相关文章:

c++ - 是否可以创建一个不会产生警告的空函数?

c++ - 如何让 C++ 从 USB 端口(如串行端口)执行 I/O

c++ - 如何使用 ICU 的 CalendarAstronomer

javascript - "|>"运算符在 JavaScript 中有什么作用?

c++ - Pthread 条件变量不可预测的结果

compilation - 编译时错误 "Undefined symbols for architecture x86_64"是什么意思?

c++ - 带有 EVP_PKEY_free 作为自定义删除器的 shared_ptr<EVP_PKEY> 导致堆损坏

c++ - 从文件名中删除扩展名的简单方法?

python - for/while/print *things* 在 python 中如何工作?

c# - 我如何弄清楚我需要知道什么?