簡體   English   中英

std :: bind vs std :: shared_ptr

[英]std::bind vs std::shared_ptr

無法理解如何使用shared_ptr綁定到類函數。 USE行發生錯誤,因為編譯器無法將shared_ptr轉換為A。

#include <functional>

class A {
    public:
        const bool check(void) const { return true; };
};

int _tmain(int argc, _TCHAR* argv[]) {
    const std::function<const bool(const A)> f_check = &A::check;
    auto a = std::make_shared<const A>();
    auto f_check_a = std::bind(f_check, a); // line BIND
    auto res = f_check_a(); // line USE - ERROR!!!

    return 0;
}

我可以替換行BIND來訪問智能指針的實際值:

int _tmain(int argc, _TCHAR* argv[]) {
    auto f_check = &A::check;
    auto a = std::make_shared<const A>();
    auto f_check_a = std::bind(f_check, *a.get()); // line BIND
    auto res = f_check_a(); // line USE - NO ERRORS

    return 0;
}

現在,代碼已編譯,可能會起作用。 但是我想知道-使用智能指針中的原始值是否可以接受? 我可以以某種方式使用shared_ptr代替原始值嗎?

UPD2:看來我的同事找到了一個不錯的解決方法:

class A {
    public:
        const bool check(void) const { return true; };
};

using p_func = const bool(A::*)() const;

int _tmain(int argc, _TCHAR* argv[]) {
    auto a = std::make_shared<const A>();
    p_func b = &A::check;
    auto f_check_a = std::bind(b, a);
    auto res = f_check_a();
}

現在,我可以將b作為參數發送並綁定到shared_ptr

UPD:我不能在實際任務中使用lambda。 這是真實項目中的更多代碼:

#include <functional>
#include <algorithm>

class Block {
    public:
        const bool check1(void) const { return false; };
        const bool check2(void) const { return false; };
        const bool check3(void) const { return false; };
};

using block_t = std::shared_ptr<const Block>;

class Worker {
    private:
        std::vector<const block_t> _container;
    public:
        void processor(const std::function<const bool(const Block)> f_check) {
            block_t my_block = nullptr;
            auto lambda = [my_block, f_check](const block_t block) mutable {
                auto function_check = std::bind(f_check, *block.get());
                if (function_check()) {
                    my_block = block;
                    return true;
                }
                return false;
            };
            std::find_if(_container.begin(), _container.end(), lambda);
        }
};

void test(block_t block) {
    Worker worker;
    worker.processor(&Block::check1);
    worker.processor(&Block::check2);
    worker.processor(&Block::check3);
}

UPD3:固定代碼,無智能指針解引用:

#include <functional>
#include <algorithm>

class Block {
public:
    const bool check1(void) const { return false; };
    const bool check2(void) const { return false; };
    const bool check3(void) const { return false; };
};

using block_t = std::shared_ptr<const Block>;
using p_func = const bool(Block::*)() const;

class Worker {
private:
    std::vector<const block_t> _container;
public:
    void processor(p_func f_check) {
        block_t my_block = nullptr;
        auto lambda = [my_block, f_check](const block_t block) mutable {
            auto function_check = std::bind(f_check, block);
            if (function_check()) {
                my_block = block;
                return true;
            }
            return false;
        };
        std::find_if(_container.begin(), _container.end(), lambda);
    }
};

void test(block_t block) {
    Worker worker;
    worker.processor(&Block::check1);
    worker.processor(&Block::check2);
    worker.processor(&Block::check3);
}

您的問題是,您首先要從成員函數創建std::function ,並期待一個A實例,然后嘗試將其綁定到shared_ptr 您可以跳過該部分:

auto a = std::make_shared<const A>();
auto f_check_a = std::bind(&A::check, a);
auto res = f_check_a(); 

std::bind知道如何直接將成員函數綁定到shared_ptr

您必須使用std::bind嗎? 您可以改用lambda。

auto f_check_a = [=]{ return a->check(); };

function希望獲得A的實例,而不是shared_ptr<A> ,因此我相信,對您的問題的回答基本上是肯定的。

但是,我將對您的代碼進行2次更改,如下所示(請參閱我的評論):

const std::function<const bool(const A&)> f_check = &A::check; // <-- Added & after A here
auto a = std::make_shared<const A>();
auto f_check_a = std::bind(f_check, *a); // <-- no need to call get() on a
auto res = f_check_a(); // line USE - ERROR!!!

但是我想知道-使用智能指針中的原始值是否可以接受?

是的,但是您可以只寫*a代替*a.get()

但是,從bind返回的調用包裝器具有對A對象的引用,因此您有責任確保引用保持有效。 如果綁定了shared_ptr ,則將增加引用計數並使對象保持活動狀態。

我可以以某種方式使用shared_ptr代替原始值嗎?

如果使用std::function<const bool(const A)>則無法傳遞shared_ptr<const A>

當您使用std::function<const bool(const A)>您將創建一個具有完全調用簽名const bool(const A)的可調用類型,因此必須向其傳遞一個可轉換為const Ashared_ptr<const A>不能轉換為const A

一種解決方法是使用lambda組合std::functionshared_ptr

            auto function_check = [] { return f_check(*block); };
            if (function_check()) {

但是,您正在嘗試解決不應該存在的問題,只需執行以下操作即可:

            if (f_check(*block)) {
                my_block = block;
                return true;
            }
            return false;

然后,您無需bind任何東西。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM