C ++将迭代器转换为指针(并将end()转换为nullptr)

时间:2014-02-14 01:36:17

标签: c++ c++11

我经常发现自己处于这样的情况:我希望获得指向容器中对象的指针(如果存在)或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的一次调用?

3 个答案:

答案 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;
}
相关问题