[Решение с использованием макроса в конце, потому что оно довольно ужасное и отвратительное.]
Если вы не возражаете против создания копий, возможно, лучше использовать std::find
:
std::array<int, 4> values = { X, Y, Z, W };
if (std::find(values.begin(), values.end(), 3) != values.end()) { }
Часто приятно обернуть эту строку в функцию:
template <typename Container, typename Value>
bool contains(const Container& c, const Value& v)
{
return std::find(c.begin(), c.end(), v) != c.end();
}
используется как:
std::array<int, 4> values = { X, Y, Z, W };
if (contains(values, 3)) { }
В C ++ 0x вы можете использоватьсписок инициализаторов вместо создания временного массива:
if (contains({ X, Y, Z, W }, 3)) { }
(Это работает в gcc 4.5+; я не знаю ни одного другого компилятора, поддерживающего эту функцию C ++ 0x.)
Если вы действительно хотите избежать копирования объектов (например, если они большие или дорогостоящие для копирования), вы можете использовать косвенную версию той же функции:
#include <boost/iterator/indirect_iterator.hpp>
template <typename Container, typename Value>
bool indirect_contains(const Container& c, const Value& v)
{
return std::find(boost::make_indirect_iterator(c.begin()),
boost::make_indirect_iterator(c.end()),
v)
!= boost::make_indirect_iterator(c.end());
}
Используется как:
std::array<int*, 4> values = { &X, &Y, &Z, &W };
if (indirect_contains(values, 3)) { }
Или со списком инициализатора C ++ 0x:
if (indirect_contains({ &X, &Y, &Z, &W }, 3)) { }
Поскольку Джонатан Леффлер упомянул Boost.Preprocessor, вот как это решение будет выглядеть:
#include <boost/preprocessor.hpp>
#define SEQUENCE_CONTAINS_IMPL(r, data, i, elem) \
BOOST_PP_IIF(BOOST_PP_EQUAL(i, 0), BOOST_PP_EMPTY(), ||) \
((elem) == (data))
#define SEQUENCE_CONTAINS(elements, value) \
(BOOST_PP_SEQ_FOR_EACH_I(SEQUENCE_CONTAINS_IMPL, value, elements))
Используется как:
if (SEQUENCE_CONTAINS((X)(Y)(Z)(W), 3)) { }
Что расширяется до:
if ((((X) == (3)) ||
((Y) == (3)) ||
((Z) == (3)) ||
((W) == (3)))) { }
(Это ужасно и ужасно; я бы не стал использовать тего в моем коде, но если вы действительно беспокоитесь о том, что создаются копии двух или трех значений, вы, вероятно, тоже не захотите делать вызов функции.)