我经常发现自己处于这样的情况:我希望获得指向容器中对象的指针(如果存在)或nullptr
(如果不存在)。这导致我需要检查迭代器是否等于std::end(container)
,然后取消引用迭代器或返回nullptr
。
例如:
std::map<int, bar> container;
...
// case 1: passing to a function that needs a pointer...
auto iter = container.find(5);
foo(iter != container.end() ? &(*iter) : nullptr);
// case 2: executing a branch if the pointer is valid
auto iter = container.find(5);
if (auto ptr = iter != container.end() ? &(*iter) : nullptr)
{
// do stuff
}
我讨厌如何在一行中执行这些操作,因为我们需要两次引用iter
,这会导致iter
引入父作用域。
在父作用域中不需要iter
的一种方法是使用lambda我猜(未经测试):
if (auto ptr = [&](container::iterator i){ return i == container.end() ? nullptr : &(*i); }(container.find(5)))
{
//do stuff
}
但它似乎非常冗长。有没有其他有效的方法(使用find
的一次调用?
答案 0 :(得分:1)
template<class C, class L>
decltype(&*std::begin(std::declval<C>()))
as_ptr(C&&c, L&&f){
auto it = std::forward<L>(f)();
if (it==c.end()) return nullptr;
return &*it;
}
auto* p = as_ptr(vec, [&]{return vec.find(x);});
begin
上的完整广告会更好。
这使您可以在容器上运行任何算法并获取指针或您想要的空值。
答案 1 :(得分:1)
我会使用一些模板函数,一个用于容器key_type
(因此是一个find
成员函数),另一个用于查找value_type
的值,使用{ {1}}:
std::find
答案 2 :(得分:0)
一个简单的吸气器怎么样?
template<class Container>
auto get_value(Container& c, typename Container::key_type x)
-> decltype(*c.begin())*
{
auto it = c.find(x);
return (it != c.end())
? &*it;
: nullptr;
}