Почему копия ctor вызывается дважды при использовании std :: bind? - PullRequest
0 голосов
/ 27 мая 2018

Я играю с std::function и std::bind, чтобы понять, как копируются аргументы и можно ли сохранить некоторые операции копирования.

Я понимаю, что при использовании std::bind аргументы передаются по значению, а не по ссылке (если не указано std::ref).Однако, когда я запускаю следующий фрагмент, конструктор копирования вызывается дважды.Может кто-нибудь объяснить, почему?

struct token
{
    static int i;
    int code;

    token()
        : code(i++)
    {
        cout << __FUNCTION__ << ": " << code << endl;
    }
    virtual ~token()
    {
        cout << __FUNCTION__ << endl;
    }

    token (token const & other)
        : code (other.code)
    {
        cout << "copy ctor: " << code << endl;
    }

    // update -- adding a move ctor
    token (token const && other)
        : code (std::move(other.code))
    {
        cout << "move ctor: " << code << endl;
    }
    // update -- end

    void boo() const
    {
            cout << __FUNCTION__ << ": " << code << endl;
    }


};

void call_boo(token const & t)
{
    t.boo();
}


int main()
{
    token t2;

    cout << "default" << endl;
    std::function< void () >(std::bind(&call_boo, t2));

    cout << "ref" << endl;
    std::function< void () >(std::bind(&call_boo, std::ref(t2)));

    cout << "move" << endl;
    std::function< void () >(std::bind(&call_boo, std::move(t2)));


    cout << "end" << endl;
    return 0;
}

При запуске это приводит к следующему выводу:

token: 1
default
// Without move ctor
// copy ctor: 1 // Makes sense. This is the passing by value.
// copy ctor: 1 // Why does this happen?
// With move ctor    
copy ctor: 1
move ctor: 1
~token
~token
ref // No copies. Once again, makes sense.
move
// Without move ctor
// copy ctor: 1
// copy ctor: 1
// With move ctor
move ctor: 1
move ctor: 1
~token
~token
end
~token

1 Ответ

0 голосов
/ 27 мая 2018

Параметры для этого конструктора std :: function всегда копируются, поэтому внутри объекта std :: function создается копия объекта привязки (в которой есть копия вашего объекта-токена).

http://en.cppreference.com/w/cpp/utility/functional/function/function

template< class F > 
function( F f );

5) Инициализирует цель с копией f.Если f - нулевой указатель на функцию или нулевой указатель на член, * это будет пустым после вызова.Этот конструктор не участвует в разрешении перегрузки, если f не является Callable для типов аргументов Args ... и возвращает тип R. (начиная с C ++ 14)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...