Я пытаюсь найти способ суммирования по std::array
из std::variant
с помощью посетителя.Я дошел до этого далеко, но я не могу понять, как определить тип посетителей, не включая запись void
в начало моего лямбда-списка посетителей.
Кто-нибудь знает, как я могу определить тип возврата лямбд в посетителе, чтобы мне не пришлось полагаться на это?
Вот что у меня сейчас есть:
#include <array>
#include <iostream>
#include <string_view>
#include <type_traits>
#include <variant>
using namespace std::literals::string_view_literals;
template<typename... Base>
struct Visitor: Base ... {
using Base::operator()...;
};
template<typename... T>
Visitor(T...) -> Visitor<T...>;
// There has to be a better way to deduce Result than what I'm doing...
template<typename... T, typename S, typename... Ss, size_t N, typename Result = typename std::result_of_t<S()>>
constexpr std::enable_if_t<std::is_arithmetic_v<Result>, Result>
summation(const Visitor<S, Ss...> &visitor, const std::array<std::variant<T...>, N> &array) {
Result sum{};
for (const auto &a: array)
sum += std::visit(visitor, a);
return sum;
}
int main() {
constexpr Visitor visitor {
// This first entry should be unnecessary, I would think:
[]() -> double { return 0; },
[](double d) -> double { return d + 3.4; },
[](int i) -> double { return i - 2; },
[](std::string_view s) -> double { return s.size(); }
};
constexpr std::array<std::variant<int, double, std::string_view>, 5> arr{9.0, 9, 3, 5.2, "hello world"sv};
constexpr auto val = summation(visitor, arr);
std::cout << val << '\n';
}
Редактировать: Я хотел бы, чтобы результат был constexpr
.
Спасибо за любую помощь.