是否可以在没有 lambda 的情况下使用 std::visit (只是一个简单的类)? [关闭]

Posted

技术标签:

【中文标题】是否可以在没有 lambda 的情况下使用 std::visit (只是一个简单的类)? [关闭]【英文标题】:Is it possible to use std::visit without lambdas (just a simple class)? [closed] 【发布时间】:2020-10-06 13:31:51 【问题描述】:

我正在尝试只使用一个简单的类来创建访问者,并为变体中的每种类型使用 operator() 的重载。

我预计这会起作用(因为我认为它对 lamdba 函数起作用):

#include <variant>
#include <iostream>

using Example = std::variant<int, float, bool>;

class ExampleVisitor 
  void operator()(int& i) 
    std::cout << "Integer: " << i << '\n';
  

  void operator()(float& f) 
    std::cout << "Float: " << f << '\n';
  

  void operator()(bool& b) 
    std::cout << "Boolean: " << b << '\n';
  
;

int main() 
  Example example = 1234;
  ExampleVisitor visitor;
  std::visit(visitor, example);

但是编译此代码(在 gcc 版本 9.3.0 上)会导致一个相当神秘的错误 error: no type named ‘type’,我无法真正理解。我认为这与std::visit 推断访问者的返回类型有关,但我不太确定修复。

完全错误:

In file included from visit.cpp:1:
/usr/include/c++/9/variant: In instantiation of ‘constexpr decltype(auto) std::__do_visit(_Visitor&&, _Variants&& ...) [with bool __use_index = false; bool __same_return_types = true; _Visitor = ExampleVisitor&; _Variants = std::variant<int, float, bool>&]’:
/usr/include/c++/9/variant:1654:24:   required from ‘constexpr decltype(auto) std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = ExampleVisitor&; _Variants = std::variant<int, float, bool>&]’
visit.cpp:23:30:   required from here
/usr/include/c++/9/variant:1634:13: error: no type named ‘type’ in ‘std::conditional_t<false, std::__detail::__variant::__variant_idx_cookie, std::invoke_result<ExampleVisitor&, int&> >’ aka ‘struct std::invoke_result<ExampleVisitor&, int&>’
 1634 |       using _Result_type = typename std::conditional_t<__use_index,
      |             ^~~~~~~~~~~~
/usr/include/c++/9/variant:1638:23: error: no type named ‘type’ in ‘std::conditional<false, std::__detail::__variant::__variant_idx_cookie, std::invoke_result<ExampleVisitor&, int&> >::type’ aka ‘struct std::invoke_result<ExampleVisitor&, int&>’
 1638 |       constexpr auto& __vtable = __detail::__variant::__gen_vtable<
      |  

【问题讨论】:

【参考方案1】:

是的,这当然是可能的。问题是,你在ExampleVisitor 中设置的重载是private,所以std::visit 找不到合适的operator() 来使用(据它所知,根本不存在operator()s)。

你可以通过设置重载public来解决这个问题:

class ExampleVisitor 
    public:
  //  ...  all overloads
;

或者通过将class 变成struct 来更改默认访问说明符。

这是demo。

【讨论】:

以上是关于是否可以在没有 lambda 的情况下使用 std::visit (只是一个简单的类)? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

如何计算 std::for_each lambda 函数所需的类型

是否可以在恒定时间内交换 std::array ?

如何在没有内联代码的情况下使用 lambda 函数部署 cloudformation?

C++ 标准是不是允许在没有开销的情况下实现 std::optional<double>

指针是不是有可能在没有任何数据副本的情况下由向量拥有?

如何在没有授权人的情况下通过 API Gateway 使 AWS Cognito 用户数据可供 Lambda 使用?