有没有办法从map :: find()获得boost :: optional结果?

时间:2018-06-05 01:25:28

标签: c++ boost

鉴于std::map<,> m,我可以这样做:

const auto iterator = m.find(k);
if (iterator != m.end())
{
    const auto& value = iterator->second;
    // ...
}

我想用boost::optional做同样的事情。类似的东西:

const auto o = boost::find_optional(m, k);
if (o)
{
    const auto& value = o.get();
    // ...
}

有没有类似的东西?

1 个答案:

答案 0 :(得分:1)

一个版本,解决了我在其他答案中注意到的一些限制:

namespace stl { 

    namespace map {

        namespace detail {
            template <typename K, typename Map>
            static auto lookup(K const &key, Map &&map) -> boost::optional<decltype(map.at(key)) &> {
                auto it = map.find(key);
                if (it != map.end())
                    return it->second;
                return boost::none;
            }
        } // namespace detail

        template <typename K, typename Map>
        static decltype(auto) lookup(K const &key, Map &&map) {
            return detail::lookup(key, std::forward<Map>(map));
        }

        template <typename K, typename Map>
        static decltype(auto) lookup(boost::optional<K> const &key, Map &&map) {
            return key ? (lookup)(*key, std::forward<Map>(map)) : boost::none;
        }

    }

    using map::lookup;
    //using set::lookup;   // extended ideas
    //using map::contains;
    //using set::contains;
}

用测试程序来演示它:

<强> Live On Coliru

#include <iostream>
#include <boost/optional/optional_io.hpp>

using stl::lookup;

template <typename Map>
void traverse(char const* startkey, Map const& m) {
    std::cout << "\nTraverse from " << startkey << ":\n";
    auto cursor = lookup(startkey, m);

    do std::cout << "Lookup result: " << cursor << "\n";
    while (cursor = lookup(cursor, m));
}

int main() {

    std::map<std::string, std::string> m { 
        { "Hello", "World" },
        { "World", "Peace" },
        { "Peace", "Troops" },
    };

    traverse("Hello", m);

    // mutation:
    if (auto peace = lookup("Peace", m))
        *peace = "Love";

    traverse("Hello", m);
}

打印

Traverse from Hello:
Lookup result:  World
Lookup result:  Peace
Lookup result:  Troops

Traverse from Hello:
Lookup result:  World
Lookup result:  Peace
Lookup result:  Love