【问题标题】:Function passing by reference accepts reference to class with operator()通过引用传递的函数接受对带有 operator() 的类的引用
【发布时间】:2012-09-06 01:23:47
【问题描述】:

所以,我对此想得越多,它的合法性就显得越奇怪。当我将 memoizer 仿函数的一个实例传递给它的构造函数时,编译器不会抱怨。在 memoizer 模板中应该如何读取“f”?似乎使用相同的类型声明 OutputT (&f) InputT 它可以通过引用来引用函数,或者——我认为这是非法的——对成员函数的引用,即 operator() 类实例的 @987654323 @。是否应该将 f 解读为“对定义了 operator() 的事物的引用?”

#include <map>
#include <iostream>

template<typename OutputT, typename InputT>
class memoizer
{
private:
    OutputT (&f) (InputT);
    std::map<InputT,OutputT> dat;

public:
    memoizer( OutputT (&f) ( InputT ) ) : f(f) { }

    OutputT operator()( InputT t )
    {
        if( dat.count(t)==0 )
            dat[t] = f(t);
        return dat[t];
    }
};

int fib( int n )
{
    if( n < 2 ) return 1;
    return fib( n-2 ) + fib( n-1 );
}

int main()
{
    memoizer<int,int> fib_memo( fib );
    memoizer<int,int> fib_memo_memo( fib_memo );    

    std::cout << fib( 12 ) << "\n";
    std::cout << fib_memo( 12 ) << "\n";
    std::cout << fib_memo_memo( 12 ) << "\n";
}

我的意思是,不要误会我的意思:我很高兴它有效,只是看起来有点“神奇”。提前致谢。

【问题讨论】:

  • 它的工作原理是因为类型擦除。类型擦除有点“神奇”。
  • 如果您多次重复一个类型名或者如果阅读起来很烦人(在您的情况下都是如此),请使用 typedef。 typedef OutputT function_type(InputT);.
  • @GManNickG 是的,完全。这个例子有很多愚蠢之处。回想起来,我几乎向自己证明了 memoizer 模板是一个坏主意(至少对于递归函数)。一个非尾递归函数。但是关于 typedef ......你会公开还是私有?谢谢。也许这是一个不同的问题。
  • @NathanAndrewMullenax:因为它用于公共界面,所以我会将其公开。 (我的一般准则是尽可能私密。)

标签: c++ pass-by-reference


【解决方案1】:

你在欺骗自己。 fib_memo_memo 不是其f 成员变量包含fib_memo 的记忆器。您的初始化程序实际上使用了隐式复制构造函数,因此fib_memo_memo 只是fib_memo 的副本。您可以通过添加来自己验证这一点

memoizer(const memoizer &m) = delete;

你会开始遇到类似的错误

error: call to deleted constructor of 'memoizer<int, int>'
    memoizer<int,int> fib_memo_memo( fib_memo );

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 2014-02-07
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多