访问列表中的所有std :: variant并为每次访问捕获一个附加值

问题描述 投票:0回答:1

我正在尝试实现状态存储,它基本上是键-值对的映射,其中值是std::variant

以下课程效果很好。注意,它不仅打印访问的值,还打印键:

class StateStoreTest
{
    typedef std::variant<float, std::string> StateValue;

private:
    std::map<int, StateValue> States;

public:

    void SetValue(int key, const StateValue& value) { States[key] = value; }

    void VisitAllValues()
    {
        for (auto& it : States)
        {
            auto key = it.first;
            std::visit([key](auto&& value) { std::cout << key << "=" << value << "\n"; }, it.second);
        }
    }
};

我可以这样使用它,并且输出符合预期:

StateStoreTest sst;
sst.SetValue(1, 123.4f);
sst.SetValue(2, "Test");
sst.VisitAllValues();

现在,我不想在VisitAllValues()中实现特定的访问者实现,但是我希望能够提供可调用VisitAllValues()方法的访问者。在该可访问访客中,我想同时访问密钥和访问值。

所以基本上从呼叫者的角度来看,我希望能够做这样的事情:

sst.VisitAllValues([](auto key, auto&& value){ std::cout << key << "=" << value << "\n"; });

我想我的VisitAllValues()方法必须看起来像这样:

void VisitAllValues(??? visitor)
{
    for (auto& it : States)
    {
        auto key = it.first;
        std::visit([key](auto&& value) { visitor(key, value); }, it.second);
    }
}

但是我无法弄清楚细节(我尝试将VisitAllValues()编写为模板,但随后在调用方遇到了问题)。

我如何实现我的VisitAllValues()方法,以便它接受可同时访问ID和值的访问者?

Here是可以使用的完整玩具示例。

c++ lambda stl c++17 variant
1个回答
0
投票

在我看来,以下方法应该有效

template <typename L>
void VisitAllValues (L const & visitor)
 {
   for (auto& it : States)
    {
      auto key = it.first;
      std::visit([&](auto&& value) { visitor(key, value); }, it.second);
    }
 }

主题外:也许使用std::forward是您使用转发参考

visitor(key, std::forward<decltype(value)>(value));
© www.soinside.com 2019 - 2024. All rights reserved.