通过引用传递的函数接受对具有运算符()的类的引用

Function passing by reference accepts reference to class with operator()

本文关键字:引用 运算符 函数      更新时间:2023-10-16

所以,我越想这件事,它的合法性就越奇怪。当我将记忆器函子的一个实例传递给它的构造函数时,编译器不会抱怨。应该如何在备忘录模板中读取"f"?似乎使用相同的类型声明OutputT (&f) InputT,它可以通过引用引用函数,或者——我认为这是非法的——引用成员函数,即类memoizer<int,int>实例的operator()。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";
}

我的意思是,不要误解我的意思:我很高兴它能起作用,只是看起来有点"神奇"提前谢谢。

你在欺骗自己。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 );