English 中文(简体)
我如何缓解C++中核对仪表率的合成间接费用?
原标题:How can I ease the syntactic overhead of checking iterator values in C++?

基本来说,一比一字不出:

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
  ...
}

真正意义上的是:

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

是否有事先界定一些助手为缩短<条码>而 st的物品?

最佳回答

可通过职能模板<代码>auto_iterator_impl<>/code>加以使用。

a. 尽可能少的职能和考虑的工作执行:

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);
}

试验守则:

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;
}

产出:

found = 10
not found
found = 20
print modified values..
1000
2000

Online demo : http://www.ideone.com/MnISh

问题回答

确实,如果这意味着对你来说,那就意味着什么,怎么说:

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();
}

使用:

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

if (find_element(v, it, 12)) { /* use it */ }

我认为,最灵活的做法是写像包装这样的包装。

template<class Iterable>
bool CheckIterator(const typename Iterable::iterator& iter, const Iterable& collection)
{
    return !(iter == collection.end());
}

及其使用

    map<int,string> m;
    m[1]="hello";
    m[2]="world";
    map<int,string>::iterator it = m.find(2);
    if(CheckIterator(it,m))
    {
        cout<<it->second;
    } 

也可使用其他类型集装箱(如病媒)

如何做到这一点?

BOOST_FOREACH(auto &x : c.equal_range(...)) {
    // x is a val_t &, or const if c is const.
}

我假定,如果将<条码>x的基数改为<条码>boost:optional<val_t>,那么你实际上就不需要该信使,只是该数值,因此,参照的是K。

如果你使用<条码>boost:iterator_range/code>,而不是使用<条码>:pair: (即<代码>等于_range 回归)。

You could implement a wrapper function to do the != map.end() check for you, or you could use the preprocessor to do it using a macro like this:

#define map_find_if(iterator, container, func) 
    auto (iterator) = (func); 
    if ((iterator) != (container).end())

如此:

map_find_if(iter, map, map.find(key)) {
   // found the key
}
// else clause could go here

Using a function is probably a cleaner implementation though, and more in the "C++ way".

如果你愿意将你的守则变成一个匿名功能(如你已经使用<条码>auto,从而假定C++11)?

#include <iostream>
#include <map>

template <typename Container, typename ExecF>
void exec_if(Container const& cont, typename Container::const_iterator it, ExecF f)
{
  if (it != cont.end())
    f();
}

int main(void)
{
  std::map<int, int> bar;
  bar.insert(std::make_pair(1, 1));
  bar.insert(std::make_pair(2, 2));
  bar.insert(std::make_pair(3, 3));

  auto it = bar.find(2);
  exec_if(bar, it, [&it]()
    { 
      std::cout << it->first <<     << it->second << std::endl; 
    });

}

EDIT:现在,我认为它更清洁





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签