【问题标题】:use of std::bind and std::function使用 std::bind 和 std::function
【发布时间】:2023-03-16 11:05:02
【问题描述】:

EDIT3:如果我删除第二个 createTriangle 函数,它会起作用。那么如何绑定重载函数呢?

我有一个函数,它接受一个带有一个参数的函数对象,如下所示:

int createObject(std::function<void(int)>);

如何使用 std::bind 调用此函数?我试过这样:

createObject(std::bind(&ClassA::createTriangle, std::placeholders::_1, a, b, c, color));

但这给了我一个错误:

候选模板被忽略:无法推断模板参数

ClassA::createTriangle 是一个静态函数。


附加信息:

void ClassA::createTriangle(int id, const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c, const glm::vec3 & col) {
    /* ... */
}

int ClassB::createTriangle(const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c, const glm::vec3 & color) {
    return classCInstance.createObject(std::bind(&classA::createTriangle, std::placeholders::_1, a, b, c, color));
}

int ClassC::createObject(std::function<void(int)> f) {
    f(++id);
    return id;
}

ClassA 中还有另一个静态 createTriangle 函数,但最后一个参数不同。这可能是个问题吗? bind 不知道选择哪个 createTriangle 吗?它看起来像这样:

void ClassA::createTriangle(int id, const glm::vec3 & a, const glm::vec3 & b, const glm::vec3 & c, const std::initializer_list<glm::vec3> & colors) {
    /* ... */
}

【问题讨论】:

  • 为什么不允许我们看到ObjectInterface::createTriangle的声明?
  • @Kerrek SB:你现在是。
  • 为什么投反对票?太具体了?
  • 没有重要信息就无法回答!已恢复...
  • 一般不能绑定重载函数,这只是绑定的限制。您可以使用各种方法来消除歧义,但这并不值得,lambda 更容易。

标签: c++ c++11 std-function stdbind


【解决方案1】:

ClassA::createTriangle 是一个重载函数,如果不指定要使用的重载,就不能使用它。 std::bind 必须返回一个通用包装器,它自己无法计算,你必须指定。

这应该可行:

void (*mySpecificCreateTriangle)(int, const const glm::vec3 &, const const glm::vec3 &, const const glm::vec3 &, const const glm::vec3 &) = &createTriangle;
createObject(std::bind(mySpecificCreateTriangle, std::placeholders::_1, a, b, c, color));

由于您使用的是 C++11,因此您会更喜欢 lambda:

createObject([=](int id){ return createTriangle(id, a, b, c, color); });

【讨论】:

  • 你确定 std::function 会使用 lambda 吗?
  • @TingL:是的,std::function 的全部目的是包装任何可调用对象,包括 lambda。
  • @gartenriese 上次我检查时,如果你有int createObject(std::function&lt;void(int)&gt;); 并用 lambda createObject([=](int id){ return createTriangle(id, a, b, c, color); }); 调用它,gcc 中会出现编译错误。
  • @Ting L:我使用 clang,所以也许你对 gcc 的看法是正确的。
  • 哦,你的意思是因为退货?我没有使用返回,Juliano 一定是不小心添加的。
猜你喜欢
  • 2013-04-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-18
  • 2019-02-20
相关资源
最近更新 更多