问题标签 [non-member-functions]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
2 回答
385 浏览

templates - begin() and end() free function overload on template

I have a templated class, Iterable; for which I want to overload the begin() and end() free functions. It stores data as a vector of unique_ptr, but the interface uses boost::indirect_iterator for convenience.

My code builds and runs under CLang-3.5, but I tried on g++-4.9 and it did not. But I do not know why ? (And which compiler has the right behaviour).

And the free functions :

On g++, the error is :

So it looks like g++ sees the friend declaration as another function ?

0 投票
3 回答
844 浏览

c++ - C++ 中的切片和运算符重载

背景资料

我已经用 Java 编程了一段时间,几个月前我才切换到 C++,所以如果答案只是我错过的一些愚蠢的事情,我深表歉意!既然都说了这么多,是时候讨论手头的问题了!我正在开发一个基本的基于文​​本的游戏引擎,最近我遇到了一个有趣的具体且不太可能出现的问题。我尝试在下面的程序中以较小的规模对其进行测试,并决定仅显示(与我的实际游戏代码相反),以免阻塞屏幕,并使问题不那么复杂。下面建模的问题反映了我的实际代码的问题,只是没有蓬松的干扰。

问题

本质上,问题是多态性之一。我想重载输出运算符“<<”以用作层次结构中每个对象唯一的显示函数。问题是,当我从存储这些层次结构成员的列表中调用此运算符时,它们会失去身份并调用基类的输出运算符。通常,可以通过用简单的显示方法替换运算符重载,将显示方法标记为虚拟,然后继续他们的快乐日子来解决这个问题。我并不特别介意对代码进行更改,但现在我只是很好奇。有没有办法在层次结构中重载运算符,导致我在这里做什么?

[示例] 代码

[示例] 代码的输出

[示例] 代码的所需输出

0 投票
3 回答
641 浏览

c++ - c++ 在运算符重载函数中创建、分配新变量并将其与两个对象进行比较。

作业:
使用提供的 Alien.h 文件实现 Alien 类。在这种情况下,外星人是根据他/她的身高、体重和性别来描述的。要比较两个外星人,您可以使用以下等式确定外星人的 statusPoints 值: statusPoints = weight * height * genderValue 其中,如果外星人是男性,genderValue 为 2,如果外星人是女性,则为 3。状态点应在需要时计算,而不是作为数据成员保存。这避免了所谓的陈旧数据,其中一个数据成员(例如权重)可能会更改,而状态点变量不会得到更新。比较外星人时应使用身份。您需要重载 ==、!=、>、<、>= 和 <= 运算符来比较外星人。因此,您可能有如下语句: if(alien1 >

显然,alien1 将是 Alien 对象,alien2 也是如此。还假设他们的数据成员(身高、体重和性别)已初始化。

这是提供的 .h 文件。同样,我无法更改此文件,因为它是为我提供的。

这是我的 Alien.cpp 文件。

如果我无法更改 .h 文件,或将 statusPoints 设为成员函数,我应该在哪里在 main 或重载运算符中创建 statusPoints 变量?另外...如何将 statusPoints var 分配给对象以进行比较?

任何帮助表示赞赏。谢谢。

0 投票
1 回答
3596 浏览

c++ - 在 C++ 中重载乘法运算符

我已经为 LAPACK 编写了一个 C++ 接口,但是我遇到了一些内存问题,这让我重新考虑了一些运算符重载。

现在,我在类定义之外重载了 operator*(但作为 Matrix 类的朋友),它接受两个 Matrix 对象,分配第三个具有适当尺寸的对象,使用 D(GE/SY)MM 来计算积(存储到新分配矩阵的内部存储器中),然后返回指向该新矩阵的指针。IE

然后我利用

这很好用。我遇到的问题是每次执行此操作时都必须分配一个新矩阵。我想要做的是分配C一次矩阵并将乘积放入( )AB内部存储中。根据我在运算符重载方面的发现,我找不到一个很好的方法来做到这一点。我知道我可以使用成员函数来执行此操作,(即)但我想尽可能避免这种情况(我正在编写此代码以便于非 CSE 类型的开发)。任何想法将不胜感激。CC->data_C->mult(A,B)

0 投票
3 回答
302 浏览

c++ - 非朋友、非成员函数增加封装?

在文章非成员函数如何改进封装中,Scott Meyers 认为没有办法阻止非成员函数“发生”。

语法问题

如果你和我讨论过这个问题的许多人一样,你可能会对我的建议的句法含义有所保留,即非朋友非成员函数应该优先于成员函数,即使你购买了我的关于封装的争论。例如,假设一个类 Wombat 支持吃饭和睡觉的功能。进一步假设吃饭功能必须实现为成员函数,而睡眠功能可以实现为成员或非朋友非成员函数。如果你按照我上面的建议,你会声明这样的事情:

啊,这一切的一致性!但是这种统一是误导性的,因为世界上的功能比你的哲学所梦想的要多。

说白了就是发生非成员函数。让我们继续以 Wombat 为例。假设您编写软件来模拟这些抓取生物,并想象您经常需要您的袋熊做的一件事就是睡半个小时。显然,您可以在代码中乱扔对 的调用w.sleep(.5),但这将是很多 0.5 秒的输入时间,而且无论如何,如果这个神奇的值改变了怎么办?有很多方法可以解决这个问题,但也许最简单的方法是定义一个函数来封装您想要做的事情的细节。假设您不是 Wombat 的作者,则该函数必须是 non-member,并且您必须这样称呼它:

你有它,你可怕的句法不一致。当你想喂你的袋熊时,你会调用成员函数,但是当你想让它们打盹时,你会调用非成员函数。

如果您稍微反思一下并对自己诚实,您就会承认您与您使用的所有重要类存在这种所谓的不一致,因为没有类具有每个客户所需的所有功能。每个客户都至少添加了一些自己的便利功能,这些功能始终是非成员的。C++ 程序员已经习惯了这一点,他们对此毫不在意。有些调用使用成员语法,有些调用使用非成员语法。人们只是查找适合他们想要调用的函数的语法,然后调用它们。生活仍在继续。它在标准 C++ 库的 STL 部分尤其如此,其中一些算法是成员函数(例如,大小),一些是非成员函数(例如,唯一),而一些是两者(例如,查找)。没有人眨眼。连你都没有。

我真的无法理解他在粗体/斜体句子中所说的话。为什么它必须以非成员身份实施?为什么不直接从 Wombat 类继承您自己的 MyWombat 类,并使nap()函数成为 MyWombat 的成员?

我刚开始使用 C++,但这就是我在 Java 中可能会这样做的方式。这不是 C++ 的方式吗?如果不是,为什么会这样?

0 投票
1 回答
2782 浏览

c++ - 命名空间和自由函数

我有一个自由函数,foo定义在命名空间 N 中。 的标头foo位于全局包含搜索路径中,因此任何人都可以通过包含来调用它foo.h

foo调用另一个本地的自由函数 ,foo1它在 中定义foo.cpp

我应该放入foo1未命名的命名空间还是放入namespace N?还是没关系?

更新

我想限制 to 的foo1范围foo.cpp

0 投票
1 回答
142 浏览

c++ - 为类外的模板实现 operator!= 作为自由函数的正确方法

我在文件中有一个带有内部类的以下模板map.hpp

main.cpp我调用以下内容时,到目前为止一切正常:

但是,我想将朋友函数移出map.hpp文件并移入map.hxx包含其他实现的文件中。

问:是否可以将免费功能移动到.hxx文件中?如何?

我厌倦了在 Iterator 类中将函数声明为朋友,并在实现文件中执行了以下操作:

但是它失败了:

谢谢!

0 投票
5 回答
124 浏览

c++ - 类范围和私有成员?

我正在定义一个函数来将元素添加到vector<Point> original_points名为
void add_point(). 为什么在函数体中突出显示original_points未定义,当我使用类型限定符时:朋友(获得访问权限)并且它在类的范围内

我究竟做错了什么?

0 投票
1 回答
35 浏览

c++ - 在运算符查找中,成员优先于非成员

Stroustrup 写道:

考虑一个二元运算符@。如果 x 属于 X 类型并且 y 属于 Y 类型,则 x@y 解析如下:

• 如果X 是一个类,则查找operator@ 作为X 的成员或作为X 的基的成员;和

• 在围绕x@y 的上下文中寻找operator@ 的声明;和

• 如果 X 在命名空间 N 中定义,则在 N 中查找 operator@ 的声明;和

• 如果 Y 在命名空间 M 中定义,则在 M 中查找 operator@ 的声明。

可以找到多个 operator@s 的声明,并且使用重载解析规则(第 12.3 节)来找到最佳匹配(如果有)。仅当运算符具有至少一个用户定义类型的操作数时,才应用此查找机制。因此,将考虑用户定义的转换(§18.3.2、§18.4)。请注意,类型别名只是同义词,而不是单独的用户定义类型(第 6.5 节)。一元运算符以类似方式解析。

请注意,在运算符查找中,成员没有优先于非成员。这与查找命名函数不同

那么大胆的表达是什么意思。如果类有成员并且同时有可以在上下文中使用的非成员函数,那么不优先考虑成员吗?例如

我认为(并且编译器同意我的观点:))应该调用成员函数,但如上所述,不应优先考虑成员运算符。那么,这句话究竟是什么意思 Stroustrup 呢?

0 投票
3 回答
1091 浏览

c++ - 在 C++14 中支持 std::cbegin()

Scott Mayers 的“Effective Modern C++”中的第 13 项声明更喜欢 const_iterators 而不是迭代器。我同意,但我也想使用非成员函数而不是成员函数。根据这本书,应该有一个非成员函数std::cbegin(),并且std::cend()在 C++14 中。

为了使用这个功能,我刚刚安装了 gcc 版本 4.9.2 并使用 flag 编译-std=c++14。在我尝试使用std::cbegin(). 我开始寻找对此功能的支持,但找不到任何相关信息。例如,在gnu onlinedocs 状态下,甚至没有提到该功能。

我的问题是, c ++ 14 是否真的会得到支持std::cbegin()std::cend()或者这是书中的错误?如果它将是 C++14 功能,是否有已经支持这些功能的编译器以及 gcc 何时支持?

SO上有很多问题,begin()但这些问题是关于成员函数或constexpr-ness,而不是关于非成员变体的支持。