Дополнительные конструкторы копирования при использовании std :: function - PullRequest
1 голос
/ 20 декабря 2011

В моем проекте есть два компонента: производитель и потребитель. Производитель несет ответственность за обработку некоторой информации и предоставление результата потребителю. Результат передается с помощью объекта функции.

Я использую функцию для передачи этой информации. Вы могли видеть, как это могло бы выглядеть в коде ниже.

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

class Data {
    std::vector<int> vec;
public:
    Data()  { 
        cout << "Data()" << endl; 
    }

    Data(const Data& rr) : vec(rr.vec)  {
        cout << "Data(Data&)" << endl;
    }

    ~Data() {
        cout << "~Data()" << endl;
    }

    Data(Data&& rr) : vec(move(rr.vec)) {
        cout << "Data(Data&&)" << endl;
    }

    void get() {
    }
};

class Producer {
public:
    void process(function<void(Data)> f) {
        Data data; 
        f(move(data));
    }

    void process2(void(&pf)(Data))  {
        Data c; 
        pf(move(c));
    }

};

void Consume(Data a) {
    cout << "Consume(data)" << endl;
}

int main() {
    {
        cout << "use function() " << endl;
        Producer p;
        p.process([](Data a) {
            cout << "Consume(data)" << endl;
        });
    }

    {
        cout << endl;
        cout << "use function pointer" << endl;
        Producer p;;
        p.process2(Consume);
    }
    return 0;
}

имеет следующий вывод

    use function() 
    Data()
    Data(Data&&)
    Data(Data&)
    Data(Data&)
    Consume(data)
    ~Data()
    ~Data()
    ~Data()
    ~Data()

    use function pointer
    Data()
    Data(Data&&)
    Consume(data)
    ~Data()
    ~Data()

Существуют дополнительные конструкторы копирования, когда используется функциональный объект.

Я сделал что-то не так? Можно ли избавиться от этих лишних конструкторов?

Заранее спасибо.

Я использую VC10 SP1.

1 Ответ

0 голосов
/ 18 января 2012

У вас есть несколько вариантов здесь.

  • Не используйте std::function, ваша не захватывающая лямбда конвертируется в void(*)(Data)
  • Не используйте std::function, создайте свои шаблоны функций, компилятор может определить скрытый тип лямбды.
  • Не копируйте объекты, передавайте их как указатели или ссылки. В зависимости от того, что делает полная версия программы, может быть более эффективно выделить в куче и использовать std::unique_ptr.
...