鉴于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();
// ...
}
有没有类似的东西?
答案 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