2

我想从函数对象中检索状态。但是函数对象已被转换为function<>模板。我该怎么做?

我是说:

功能对象:

class Counter {
private:
    int counter_;
public:
    Counter():counter_(0) {cout << "Constructor() called" << endl;}
    Counter(int a):counter_(a) {cout << "Constructor(a) called" << endl;}

    void operator()(int sum) {
        cout << counter_++ + sum << endl;
    }

int getCounter() { return counter_;}
};

在主要。我的第一步是直接使用对象:

int main() {
    Counter a(10);
    a(0);
    a(0);

    cout << "Counter: " << a.getCounter() << endl;

它的节目:

构造函数(a)调用

10

11

计数器:12

没关系,这是我所期望的。

但在

Counter b(10);
function<void(int)> f = b;
f(0);
f(0);
cout << "Counter: " << b.getCounter() << endl;

表明

构造函数(a)调用

10

11

计数器:10

啊!,我认为 f 是真实对象的包装器,所以修改f我们真的修改了b. 否:f有 的副本b,但我无法调用f.getCounter()我如何从 中获取 State (counter_var) f

我不能直接使用Counter类(在这个例子中),因为我有一些其他类似的具有相同签名“void(int)”的类,我想在调用者函数中模糊地使用它们。

我可以完全避免std::function为我的所有函数对象使用公共基类的模板,但我认为有一个解决方案更 C++11 与 STL 和模板......

那么,有没有解决方案?

谢谢

4

2 回答 2

3

从引用包装器创建函数:

function<void(int)> f = std::ref(b);

给出结果:

Constructor(a) called
10
11
Counter: 12

当然,您需要确保在销毁计数器后不调用该函数。

如果您需要从函数对象访问计数器,请使用其target成员:

if (Counter * c = f.target<Counter>()) {
    std::cout << "Counter: " << c->getCounter() << '\n';
} else {
    std::cout << "Not a counter.\n";
}
于 2012-06-22T13:12:19.253 回答
2

这不是演员表:

function<void(int)> f = b;

Astd::function已被构造,以您的函数对象的副本作为其目标。

您可以使目标成为对您的函数对象的引用:

function<void(int)> f = std::ref(b);

或者让f包含一个副本,然后从以下位置检索该副本f

Counter* c = f.target<Counter>();
cout << "Counter: " << c->getCounter() << endl;

f包含副本通常更安全,因为您不必担心b.

于 2012-06-22T14:22:34.027 回答