模板可用于std :: variant的访问吗? [英] Would a template work for std::variant's visit?

查看:59
本文介绍了模板可用于std :: variant的访问吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我之前曾问过关于 std :: variant 的问题代码>.考虑到该变体保存的类型都可以通过 std :: cout 打印,是否有一种简单的方法来实现访问者?

Earlier I asked this question about std::variant. Considering that the types hold by the variant are all printable by std::cout, is there a simple way to implement a visitor?

此处涵盖每种类型的lambda,但是它们都做相同的事情( std :: string 除外): std :: cout<<arg<<''; .有没有办法不重复我的自我?

Here for example, all the way down you have several lambdas to cover each type, but all do the same thing (except std::string): std::cout << arg << ' ';. Is there a way to not repeat my self?

std::visit(overloaded {
            [](int arg) { std::cout << arg; },
            [](long arg) { std::cout << arg; },
            [](double arg) { std::cout << arg; }
            // I removed the std::string case
        }, v); // v is the std::variant

并改写:

   std::visit(  [](auto arg) { std::cout << arg; }, v);

或类似的东西

template<typename T>
void printer(T arg) {std::cout << arg; }
//.......
std::visit(printer, v);

推荐答案

无需复制

std::visit(  [](auto&& arg) { std::cout << arg; }, v);

这通过(转发)引用获取 arg .我不用去转发它.我不在乎它到底是右值还是左值.

this takes arg by (forwarding) reference. I don't bother forwarding it; I don't care if it is an rvalue or lvalue really.

模板功能不起作用,因为访问需要一个对象,而模板功能不是功能的对象;您还不能(现在)将重载集名称作为C ++中的对象传递.

The template function doesn't work, because visit requires an object, and template functions aren't objects of functions; you cannot (yet) pass overload set names as objects in C++.

overload 技巧主要是在您要调度其他行为时使用的.

The overload trick is mainly when you want to dispatch different behavior.

您可以做的一件事是

template<typename T>
void printer(T arg) {std::cout << arg; }

std::visit([](auto&&arg){printer(arg);}, v);

#define RETURNS(...) \
   noexcept(noexcept(__VA_ARGS__)) \
   -> decltype( __VA_ARGS__ )

#define OVERLOADS_OF(...) \
  [](auto&&...args) \
  RETURNS( __VA_ARGS__(decltype(args)(args)...) ) \
  { return __VA_ARGS__(decltype(args)(args)...); }

然后我们得到:

template<typename T>
void printer(T arg) {std::cout << arg; }

std::visit(OVERLOADS_OF(printer), v);

创建一个匿名对象,该对象表示由令牌 printer 命名的功能的重载集合.

which creates an anonymous object that represents the overload set of functions named by the token printer.

这篇关于模板可用于std :: variant的访问吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆