C++级联operator[]到operator()参数列表?
我有一个带有 operator()
的类,如下所示:
struct S
{
int operator()(int a, int b, int c, int d);
};
示例用法:
S s;
int i = s(1, 2, 3, 4);
我需要我的用户能够使用备用语法:
int i = s[1][2][3][4]; // equivalent to calling s(1, 2, 3, 4)
我知道我需要添加 S::operator[]( int a)
并且它需要返回一个辅助对象。但除此之外,一切都变得有点复杂,我有一种感觉,我正在重新发明轮子,因为其他库(例如多维数组)可能已经提供了类似的接口。
理想情况下,我只需使用现有的库来实现此目标。如果做不到这一点,我怎样才能用最通用的代码来实现我的目标呢?
编辑:理想情况下,我希望在现代优化编译器上实现这一目标,而不会造成任何运行时损失。
I have a class with operator()
like this:
struct S
{
int operator()(int a, int b, int c, int d);
};
Example usage:
S s;
int i = s(1, 2, 3, 4);
I need my users to be able to use an alternate syntax:
int i = s[1][2][3][4]; // equivalent to calling s(1, 2, 3, 4)
I know I need to add S::operator[](int a)
and that it needs to return a helper object. But beyond that it all gets a bit complex and I have a feeling that I am reinventing the wheel since other libraries (e.g. multidimensional arrays) probably already offer similar interface.
Ideally I'd just use an existing library to achieve this goal. Failing that, how can I achieve my goal with the most generic code?
Edit: ideally I'd like to achieve this without any runtime penalty on a modern optimizing compiler.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
开始了!
首先,代码有点混乱——我必须在执行过程中累积参数值,而我能想到的唯一方法(至少在 C++03 中)是将立即索引设置为数组。
我已经在 G++ 4.5.1 (Windows / MinGW) 上检查过这一点,并确认在 -O3 上调用:
s[1][2][3][4];
产生相同的汇编代码as:
s(1,2,3,4);
因此,如果您的编译器能够智能优化,则不会产生运行时开销。 干得好,GCC 团队!
代码如下:
说真的,请不要使用这个,只坚持使用
operator()
。 :) 干杯!Here we go!
First of all, the code is kind of messy- I have to accumulate the argument values as we go, and the only way I could think of (at least in C++03) is to pass the immediate indices set around as arrays.
I have checked this on G++ 4.5.1 (Windows / MinGW) and I confirm that on -O3 the call:
s[1][2][3][4];
yields the same assembler code as:
s(1,2,3,4);
So - no runtime overhead if your compiler is smart with optimisations. Good job, GCC team!
Here goes the code:
And seriously, please, don't use this and just stick with
operator()
. :) Cheers!这是对
bind
方法的尝试。我怀疑它是否特别有效,并且其中有一些令人讨厌的部分,但我将其发布以防有人知道如何修复它。请编辑:其中
s
是一个返回绑定到this
的operator()
的表达式。类似于 std::bind(std::mem_fun(S::operator(), this, _1, _2, _3, _4)) 的内容。虽然我不记得 std::bind 是否已经可以处理成员函数,但可能不需要 mem_fun 。function_type::type
是std::function
,并且bound< /code> 是
function_type::typebound(function_type::type f, int p) { return std::bind(f, p, _1、_2、..._N); }
。我不确定如何递归地定义它们,但您可以将它们列出到一定限度。This is an attempt at the
bind
approach. I doubt that it's particularly efficient, and it has some nasty bits in it, but I post it in case anyone knows how to fix it. Please edit:where
s
is an expression that returnsoperator()
bound tothis
. Something along the lines ofstd::bind(std::mem_fun(S::operator(), this, _1, _2, _3, _4))
. Although I can't remember whetherstd::bind
can already handle member functions,mem_fun
might not be needed.function_type<N>::type
isstd::function<int, [int, ... n times]>
, andbound<N>
isfunction_type<N>::type bound(function_type<N+1>::type f, int p) { return std::bind(f, p, _1, _2, ... _N); }
. I'm not immediately sure how to define those recursively, but you could just list them up to some limit.我会完全避免这种情况,只提供
operator()
,但如果您真的想尝试一下,想法是您的类型的operator[]
将返回一个对象一个帮助器类型,它保存对对象的引用和传入的值。该帮助器类将通过再次存储对原始对象的引用和两个调用的参数来实现operator[]到[]
。除了最后一个级别(即相当数量的助手)之外,所有级别都必须执行此操作。在最后一个级别,operator[]
将获取其参数以及所有先前存储的值,并使用所有先前存储的值加上当前值调用operator()
。一种常见的表述方式是,每个中间类型绑定对
operator()
调用的参数之一,最后一个使用所有绑定参数执行调用。根据您是否想要支持更多或更少的数组维度,您可能希望/需要使其变得更加复杂以使其通用。一般来说,这是不值得付出努力的,仅仅提供
operator()
通常就是解决方案。请记住,最好让事情尽可能简单:更少的编写工作和更少的维护工作。I would avoid this altogether and offer just
operator()
, but if you really want to give it a shot, the idea is that your type'soperator[]
would return an object of a helper type that holds both a reference to your object and the value that was passed in. That helper class will implementoperator[]
by again storing a reference to the original object and the arguments to both calls to[]
. This would have to be done for all but the last level (I.e. a fair amount of helpers). I the last level,operator[]
will take its argument together with all previously stored values and calloperator()
with all of the previously stored values plus the current value.A common way of phrasing this is saying that each intermetiate type binds one of the arguments of the call to
operator()
, with the last one executing the call with all bound arguments.Depending on whether you want to support more or less number of dimensions of arrays you might want/need to complicate this even more to make it generic. In general it is not worth the effort and just offering
operator()
is usually the solution. Remember that it is better to keep things as simple as possible: less effort to write and much less effort to maintain.这是一个支持任意参数和返回类型的 Fusion 实现。感谢任何能够实现此功能的人(如果您这样做,请告诉我)!
Here is a Fusion implementation that supports arbitrary parameter and return types. Kudos to anyone that can get this working (please let me know if you do)!