Здравствуйте, MarcoPolo, Вы писали:
MP>Можно ли в C++ 14 как-нибудь (коротко) выразить конструкцию, аналогичную питоновской:
написать шаблонную функцию in от переменного числа аргументов?
Здравствуйте, MarcoPolo, Вы писали:
MP>Уважаемые коллеги,
MP>Можно ли в C++ 14 как-нибудь (коротко) выразить конструкцию, аналогичную питоновской:
MP>[python]
MP>if x in (1,2,4,6,7):
Здравствуйте, MarcoPolo, Вы писали:
MP>Уважаемые коллеги,
MP>Можно ли в C++ 14 как-нибудь (коротко) выразить конструкцию, аналогичную питоновской:
MP>
MP>if x in (1,2,4,6,7):
MP> print('x is either 1,2,4,6 or 7')
MP>else:
MP> print('x is something else')
MP>
есть целая лекция по этому поводу,
там сравниваются разные подходы и даже смотрят получившийся
ассемблер чтобы убедиться что генерируется нормальный код:
Здравствуйте, MarcoPolo, Вы писали:
MP>Можно ли в C++ 14 как-нибудь (коротко) выразить конструкцию, аналогичную питоновской: MP>
MP>if x in (1,2,4,6,7):
MP> print('x is either 1,2,4,6 or 7')
MP>else:
MP> print('x is something else')
MP>
MP>Понятное, что можно сделать вектор, потом воспользоваться find_if и т.д. Но это уже несколько строк, а хотелось бы in-place.
Зачем несколько строк? Пишем по месту:
#include <iostream>
#include <initializer_list>
#include <algorithm>
int main() {
int x = 7;
if (const auto a = {1,2,4,6,7}; a.end() != std::find(a.begin(), a.end(), x) )
std::cout << "x is either 1,2,4,6 or 7" << std::endl;
else
std::cout << "x is something else" << std::endl;
// your code goes herereturn 0;
}
J>if std::set({1,2,4,6,7}).count(x)
J> std::cout << "x is either 1,2,4,6 or 7" << std::endl;
J>
Поиск по списку с полным копированием списка? Причем с двойным копированием — сначала в initializer_list, затем в set — в случае если элементы списка заданы не prvalue выражениями. Ну, для простых типов, наверное, приемлемо.
J>>if std::set({1,2,4,6,7}).count(x)
J>> std::cout << "x is either 1,2,4,6 or 7" << std::endl;
J>>
R>Поиск по списку с полным копированием списка? Причем с двойным копированием — сначала в initializer_list, затем в set — в случае если элементы списка заданы не prvalue выражениями. Ну, для простых типов, наверное, приемлемо.
Есть вариант без двойного копирования, но с бустом:
if (boost::algorithm::any_of_equal(std::initializer_list<int>{1,2,4,6,7}, x))
std::cout << "x is either 1,2,4,6 or 7" << std::endl;
Здравствуйте, rg45, Вы писали:
R>Поиск по списку с полным копированием списка? Причем с двойным копированием — сначала в initializer_list, затем в set — в случае если элементы списка заданы не prvalue выражениями. Ну, для простых типов, наверное, приемлемо.
Это, конечно, как раз для тривиальных случаев типа описанного в вопросе, там где хоть 10 раз скопируй все туда-сюда — на производительности это не особо скажется.)
А>>if (boost::algorithm::any_of_equal(std::initializer_list<int>{1,2,4,6,7}, x))
А>> std::cout << "x is either 1,2,4,6 or 7" << std::endl;
А>>
R>Заменяем "{1,2,3,4,6,7}" на "{a,b,c,d,e}" и все равно получаем копирование.
Это копирование и имелось в виду. Нет второго копирования в std::set.
R>Да и назвать такое выражение "синтаксическическим сахаром" как-то язык не поворачивается. Лично мне больше по душе "in_list(x, a, b, c, d, e)".