【问题标题】:Using std::bind with std::visit将 std::bind 与 std::visit 一起使用
【发布时间】:2017-12-29 14:35:37
【问题描述】:

我正在尝试将std::bindstd::visit 一起使用以获得绑定访问者的功能。

我得到一个“没有重载函数的实例”,但我不知道我在绑定方面做错了什么。

我如何利用std::bind 来捕获访客?

#include <variant>
#include <functional>
#include <iostream>

using Somenum = std::variant<uint64_t, double>;

struct Visitor {
    uint64_t operator()(const uint64_t& num) const {
        return num;
    }
    uint64_t operator()(const double& num) const{
        return 5;
    }
};

int main(int argc, char **argv) {
    const Somenum a = 3.0;
    const Somenum b = (uint64_t)6;
    const Visitor v{};
    const auto f = std::bind(std::visit<Visitor, Somenum>, v, std::placeholders::_1);
    const auto f2 = [&v](Somenum x) {
        return std::visit(v, x);
    };

    std::cout << f(a) << std::endl << f(b)<< std::endl;

    std::cout << f2(a) << std::endl << f2(b) << std::endl;
    return 0;
}

实际上,我希望 ff2 具有相同的行为

删除调用f 的行允许编译所有内容。

【问题讨论】:

  • 不要使用需要做std::get&lt;uint64_t&gt;(s) 来获取价值,在某个地方?也许std::holds_alternative&lt;uint64_t&gt;(s) 检查变体是否具有该类型,也许? double 也是如此。
  • 不这么认为。我应该在哪里做?我认为 std::visit 应该可以处理。
  • 为什么还要在这里使用std::bind 而不是lambda?您将 C++1z 的最新热度与笨拙的旧东西混合在一起,这些东西首先有助于表明语言中对 lambda 的需求。

标签: c++ c++17 variant stdbind


【解决方案1】:

我无法解释 &lt;unresolved overloaded function type&gt; 错误 - 但无论如何你所做的都是不正确的。 std::visit 需要一堆转发引用,所以 std::visit&lt;Visitor, Somenum&gt; 是一个函数指针,其类型类似于:

decltype(auto)(*)(Visitor&&, Somenum&&);

那些是右值引用。但是您实际上并没有使用右值调用此函数,而是使用左值调用它。 const 左值偶数。所以你想要的版本真的是std::visit&lt;Visitor const&amp;, Somenum const&amp;&gt;。这有效:

auto p = std::visit<Visitor const&, Somenum const&>;
const auto f = std::bind(p, v, std::placeholders::_1);

再次,我不确定您为什么需要预先声明 p


这应该可以说明为什么强烈推荐使用 lambda。您不必在模板参数推导之前手动操作即可!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-03
    • 1970-01-01
    • 2012-10-28
    • 1970-01-01
    • 1970-01-01
    • 2014-09-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多