如何减轻在C++中检查迭代器值的语法开销?

Mar*_* Ba 14 c++ iterator stl

基本上,我有点厌倦写作:

std::map<key_t, val_t> the_map;
...
auto iterator = the_map.find(...);
if(iterator != the_map.end()) { // note the "inversed" logic and logically superflous end() call
  ...
}
Run Code Online (Sandbox Code Playgroud)

真正有意义的是:

if(auto x=the_map.find(...)) {
  ... // x could either be an iterator or maybe something like boost::optional<val_t>
}
Run Code Online (Sandbox Code Playgroud)

是否有一些现有技术定义了一些辅助工具来缩短!= container.end()语法,或者我是唯一一个因此而烦恼的人?

Naw*_*waz 7

您可以编写一个类模板auto_iterator_impl并通过函数模板使用它,该函数模板auto_iterator返回一个实例auto_iterator_impl,可以隐式转换为truefalse:

具有最少功能和考虑的工作实施:

template<typename C>
struct auto_iterator_impl
{
    C & c;
    typename C::iterator  it;
    auto_iterator_impl(C & c,  typename C::iterator & it) : c(c), it(it) {}
    operator bool() const { return it != c.end(); }
    typename C::iterator operator->() { return it; }
};

template<typename C>
auto_iterator_impl<C> auto_iterator(C & c, typename C::iterator  it)
{
    return auto_iterator_impl<C>(c, it);
}
Run Code Online (Sandbox Code Playgroud)

测试代码:

void test(std::map<int, int> & m, int key)
{
    if (auto x = auto_iterator(m, m.find(key)))
    {
        std::cout << "found = " << x->second << std::endl;
        x->second *= 100; //change it
    }
    else
        std::cout << "not found" << std::endl;
}

int main()
{
    std::map<int,int> m;
    m[1] = 10;
    m[2] = 20;  
    test(m, 1);
    test(m, 3);
    test(m, 2);

    std::cout <<"print modified values.." <<std::endl;
    std::cout << m[1] << std::endl;
    std::cout << m[2] << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

输出:

found = 10
not found
found = 20
print modified values..
1000
2000
Run Code Online (Sandbox Code Playgroud)

在线演示:http://www.ideone.com/MnISh


Ker*_* SB 7

好吧,如果它对你来说意义重大,那么一个小包装器怎么样:

template <typename Container>
inline bool find_element(Container const & c,
                         typename Container::const_iterator & it,
                         typename Container::value_type const & val)
{
  return (it = c.find(val)) == c.end();
}
Run Code Online (Sandbox Code Playgroud)

用法:

std::vector<int> v;
std::vector<int>::const_iterator it;

if (find_element(v, it, 12)) { /* use it */ }
Run Code Online (Sandbox Code Playgroud)