std::bind vs std::shared_ptr
std::bind vs std::shared_ptr
无法理解如何使用绑定到类函数的shared_ptr。由于编译器无法将shared_ptr转换为A,因此在USE行出现错误。
#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();
CCD_ 4知道如何将成员函数直接绑定到CCD_。
必须使用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 A
的参数,而shared_ptr<const A>
不可转换为const A
。
一种变通方法是使用lambda来组合std::function
和shared_ptr
:
auto function_check = [] { return f_check(*block); };
if (function_check()) {
然而,你正试图解决一个不应该存在的问题,只需这样做:
if (f_check(*block)) {
my_block = block;
return true;
}
return false;
那么你就不需要bind
了。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- 引用 std::shared:ptr 以避免引用计数
- C++14 unique_ptr并使用已删除的函数'std::unique-ptr' unique_ptr错误
- 使用std :: String ptr的错误打印std :: String
- C++中的大小释放:全局运算符delete的正确行为是什么(void*ptr,std::size_t size)
- std::哈希表示无序映射中的唯一 PTR
- boost::shared_ptr和std::shared-ptr的同居
- 我可以用std::shared_ptr而不是boost::shared-ptr构建boost库吗
- 正确使用std智能指针以确保ptr安全
- 如何创建 std::string 包装器,它将 ptr 保留为 std::string 和 ptr 到创建该包装器实例的
- 为什么 std::string{ "const char ptr" } 有效?
- 为什么 gcc 4.9.0 中没有定义"void operator delete(void* ptr, std::size_t size) noexcept;"?
- 在 std::map 的值中使用非 ptr 是一种很好的做法吗
- 共享 PTR - C++:std::shared_ptr<T> 和 std::shared_ptr<T const> 有什么区别?