使用 std::bind 和 std::visit
Using std::bind with std::visit
我正在尝试将 std::bind
与 std::visit
一起使用以获得绑定访问者的功能。
我收到 "no instance of overloaded function" 但我不知道我在绑定方面做错了什么。
如何利用 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;
}
实际上我希望 f
和 f2
具有相同的行为
删除调用 f
的行允许编译所有内容。
我无法解释 <unresolved overloaded function type>
错误 - 但无论如何你所做的都是不正确的。 std::visit
需要一堆转发引用,所以 std::visit<Visitor, Somenum>
是一个函数指针,其类型类似于:
decltype(auto)(*)(Visitor&&, Somenum&&);
那些是右值引用。但是你实际上并不是用右值调用这个函数,你是用左值调用它。 const 左值甚至。所以你要的版本真的是std::visit<Visitor const&, Somenum const&>
。这有效:
auto p = std::visit<Visitor const&, Somenum const&>;
const auto f = std::bind(p, v, std::placeholders::_1);
同样,我不确定您为什么需要预先声明 p
。
这应该能清楚地说明为什么强烈推荐使用 lambda。您不必在模板参数推导之前手动操作就可以了!
我正在尝试将 std::bind
与 std::visit
一起使用以获得绑定访问者的功能。
我收到 "no instance of overloaded function" 但我不知道我在绑定方面做错了什么。
如何利用 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;
}
实际上我希望 f
和 f2
具有相同的行为
删除调用 f
的行允许编译所有内容。
我无法解释 <unresolved overloaded function type>
错误 - 但无论如何你所做的都是不正确的。 std::visit
需要一堆转发引用,所以 std::visit<Visitor, Somenum>
是一个函数指针,其类型类似于:
decltype(auto)(*)(Visitor&&, Somenum&&);
那些是右值引用。但是你实际上并不是用右值调用这个函数,你是用左值调用它。 const 左值甚至。所以你要的版本真的是std::visit<Visitor const&, Somenum const&>
。这有效:
auto p = std::visit<Visitor const&, Somenum const&>;
const auto f = std::bind(p, v, std::placeholders::_1);
同样,我不确定您为什么需要预先声明 p
。
这应该能清楚地说明为什么强烈推荐使用 lambda。您不必在模板参数推导之前手动操作就可以了!