Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A C++ "in" operator without cruft?

Tags:

c++

c++11

I'd like to emulate Python's in operator in C++ (11), using immedate values as you can in Python. Such as:

if x in (1, 2, 3): ...

In C++11, it seems I'm close to being able to do this:

if (IsIn(x, { 1, 2, 3 }))
    {
    }


template<typename Val, Container cont>
bool IsIn(Val const &val, Container const &cont)
    {
    return boost::find(cont, val) != cont.end();
    }

But (in g++-4.8) I get:

error: no matching function for call to 'IsIn(MyType&, <brace-enclosed initializer list>)'

I know I could do this, but that's a lot of cruft:

if (IsIn(x, std::initializer_list<MyType>{1, 2, 3 })) ...

What's the elegant solution?

UPDATE: I hadn't thought enough about compile-time vs. run-time, and I still can't decide if there's a clear winner. My IsIn(x, {}) surely has more run-time loop overhead and copies the initializer_list values, but also works with any container. The ... == any_of(... mechanism would surely compile to tighter code and doesn't copy, but only works with immediates (which was my original example) and not containers, and the sytax (to me) seems a little less straight-forward.

Since it's kind of a tie, I'm awarding it to the contributor in appreciation.

Thanks to everyone for the discussion!

like image 438
JimB Avatar asked Nov 27 '25 01:11

JimB


1 Answers

The solution was right under my nose...

template<typename Val>
bool IsIn(Val val, std::initializer_list<Val> const &cont)
    {
    return boost::find(cont, val) != cont.end(); // include <boost/range/algorithm.hpp>
    // Or if you don't want boost, include <algorithm>
    // return std::find(cont.begin(), cont.end(), val) != cont.end();
    }
like image 199
JimB Avatar answered Nov 29 '25 14:11

JimB