Теперь хотелось бы добавить версию функции , которая получала бы еще предикат или ламбду для сравнения
например :
auto res = Union( list_1, list_2, list_3, cmp());
Но не могу понять как теперь определить сигнатуру функции Union , чтобы автоматически могла выводить тип предиката после переменного количества параметров
Что вроде такого
template<typename T, typename... Ts , typename Pred>
T Union(const T& c1, const Ts&... rest , Pred pred)
{
..
}
Таким образом чтобы цчтобы мозжно было вызывать :
auto res = Union( list_1, list_2, list_3); — с компаратором по умолчанию
и
auto res = Union( list_1, list_2, list_3, cmp());
A>Но не могу понять как теперь определить сигнатуру функции Union , чтобы автоматически могла выводить тип предиката после переменного количества параметров A>Таким образом чтобы цчтобы мозжно было вызывать : A> auto res = Union( list_1, list_2, list_3); — с компаратором по умолчанию A>и A>auto res = Union( list_1, list_2, list_3, cmp());
Я бы назвал функцию, принимающую предикат, как-нибудь по-другому (UnionIf, например) и поместил бы предикат в начало списка формальных параметров.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, Alex34, Вы писали:
A>Таким образом чтобы цчтобы мозжно было вызывать : A> auto res = Union( list_1, list_2, list_3); — с компаратором по умолчанию A>и A>auto res = Union( list_1, list_2, list_3, cmp());
Можно так как-то. Все проблемы решаются еще одним уровнем абстракции
Здравствуйте, andyp, Вы писали:
A>Можно так как-то. Все проблемы решаются еще одним уровнем абстракции
Технически можно, конечно, нужно ли — вот вопрос. Семантически это другая функция. И с практической точки зрения — существует ли хоть одна причина, по которой эти функции должны иметь одно имя?
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, rg45, Вы писали:
R>Технически можно, конечно, нужно ли — вот вопрос. Семантически это другая функция. И с практической точки зрения — существует ли хоть одна причина, по которой эти функции должны иметь одно имя?
Я бы тоже отдельные семейства сделал По принципу наименьшего удивления по сравнению с стл.
А так, если в философию ударяться, такие вещи требуют имхо лютого ограничения параметров шаблонов, чтобы быть удобными и безопасными для клиента. Это приводит к тоннам кода, вычисляющего воздух, на стороне либы. Если это вызывается в паре мест, я бы вообще такое не писал
так в случае лямбды этот механизм не работает. Лучше уже поменять местами параметры, как предложили ранее. Или проверять последний параметр на наличие методов begin и end. И если false, то тогда уже делать предположение, что передан предикат, а не коллекция.
SP>так в случае лямбды этот механизм не работает. Лучше уже поменять местами параметры, как предложили ранее. Или проверять последний параметр на наличие методов begin и end. И если false, то тогда уже делать предположение, что передан предикат, а не коллекция.
В с++20 есть concept std::predicate. Надо чтобы вызывалось и возвращало bool. Можно свой дискриминатор типов похожим образом замутить. То, что я привел — просто набросок
Здравствуйте, Alex34, Вы писали:
A>Доброе времжя суток и здоровья в эти непростые дни
A>Пишу библиотеку , которая реализует функции математического редактора Wolfram Mathematica.
... A>auto res = Union( list_1, list_2, list_3, cmp());
...
А как вы планируете объединять не упорядоченные и бесконечные множества?
Здравствуйте, sergii.p, Вы писали:
SP>так ему надо передать принимаемые типы (а у нас их нет). Просто сказать ему, что нужен абы какой оператор(), который возвращает bool, не получиться.
Ну почему же нет. У нас есть входные списки, которые нужно объединить. Из них можно вытащить и тип элемента. А заодно проверить их типовую совмтестимость.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, sergii.p, Вы писали:
SP>так ему надо передать принимаемые типы (а у нас их нет). Просто сказать ему, что нужен абы какой оператор(), который возвращает bool, не получиться.
есть идея использовать class template argument deduction для std::function как-то так
Здравствуйте, andyp, Вы писали:
R>>Ну а тип параметра предиката вытаскиваем уже из типов входных списков. A>Как раз была идея не вытаскивать, а чтобы он автоматически вывелся.
А, мы уже от практических потребностей к этюдам перешли? Ну хорошо:
Здравствуйте, rg45, Вы писали:
R>А, мы уже от практических потребностей к этюдам перешли?
Ну да У std::function есть конструктор, жрущий invokable. Типы аргументов оно само должно вывести при инстанциировании. Остается проверить тип, возвращаемый функцией. Я немного подредактировал предыдущий ответ пока ты отвечал.
Здравствуйте, andyp, Вы писали:
A>Ну да У std::function есть конструктор, жрущий invokable. Типы аргументов оно само должно вывести при инстанциировании. Остается проверить тип, возвращаемый функцией. Я немного подредактировал предыдущий ответ пока ты отвечал.
Да, эта идея мне нравится. Получается органично и компактно:
template <typename T>
using is_predicate = std::is_same<bool, std::decay_t<typename decltype(std::function(std::declval<T>()))::result_type>>;
Не очень привычна пока еще эта фишка, когда параметры шаблона класса выводятся по фактическим параметрам конструктора. Будем надеяться, что подобные конструкции не будут вызывать трудностей у компиляторов.
--
Не можешь достичь желаемого — пожелай достигнутого.
Здравствуйте, andyp, Вы писали:
A>Спасибо! У меня без decay_t не работало.
Ай блин, чаинки еще не утонули не все так безоблачно. Для произвольного невызываемого типа мой вариант валится по ошибке компиляции, вместо того, чтобы вычислиться в false. Придется все-таки прикрутить SFINAE: