У меня есть класс с определенной в классе функцией-другом, которую я бы в идеале не изменял (это происходит из уже развернутого заголовка)
#include <numeric>
#include <vector>
namespace our_namespace {
template <typename T>
struct our_container {
friend our_container set_union(our_container const &, our_container const &) {
return our_container{};
}
};
} // namespace our_namespace
set_union
не объявлено вне структуры илипространство имен, но обычно его можно найти с помощью поиска, зависящего от аргумента (см. Доступ к функции-другу, определенной в классе ).Однако я столкнулся с ситуацией, когда мне нужна функция без оценки (то есть без аргументов для оценки) для вывода типа шаблона.Более конкретно, я хотел бы использовать функцию друга в качестве двоичной операции в std::accumulate
:
auto foo(std::vector<our_namespace::our_container<float>> in) {
// what I really wanted to do:
return std::accumulate(std::next(in.begin()), in.end(), *in.begin(),
set_union);
}
Единственный найденный мной обходной путь - это обернуть вызов функции в лямбду:
auto foo(std::vector<our_namespace::our_container<float>> in) {
// what I ended up doing:
return std::accumulate(std::next(in.begin()), in.end(), in[0],
[](our_namespace::our_container<float> const& a, our_namespace::our_container<float> const& b) {return set_union(a,b);});
}
(и, разумеется, я мог бы определить функцию, которая выполняет те же функции, что и лямбда).
Я пытался:
- указав пространство имен для
set_union
(что я обычно делаю, чтобы обойти ADL, но set_union
не находится в пространстве имен) - разъясняет аргументы шаблона в
set_union<our_container>
(но поиск set_union
не приводит к выводу аргумента шаблона изset_union
, и не является шаблоном) - разъясняет тип
set_union
с …,decltype(set_union) set_union);
... за исключением того, что здесь поиск set_union
завершается неудачно по той же причине и предоставляет аргументы для set_union
в decltype
просто вызовет его оценку и приведет к типу возвращаемого значения set_union
, а не к его типу.
Есть ли другой способ использовать accumulate
с ADL, чем эта лямбда