c++ template with "infinite" arguments

Viewed 480

so i have this struct:

template <typename T>
struct _vect2 {
    T x;
    T y;
    _vect2(T x, T y) : x(x), y(y) { }
    _vect2() { }
};

And i want to create a function that takes an "infinite" amount of those structs.

template <typename T, _vect2<T>... Args>
double vect_distance(Args... arguments) {}

How it should work:

struct vect_2i : public _vect2<int> {
    vect_2i() : _vect2() { }
    vect_2i(int x, int y) : _vect2(x, y) { }
};

vect_2i vect1, vect2;
auto distance = vect_distance(vect1, vect2);

With this code i get a syntax error and i don't know why. What is the correct way to take the arguments?

1 Answers

You can deduce the first argument's type, and force others to derive from/be a vector of the same deduced T type.

In :

#include <concepts>
template <typename T>
double vect_distance(const vect2<T>& head,
                     const std::derived_from<vect2<T>> auto&... tail);

In :

#include <type_traits>
template <typename T, typename... Ts>
auto vect_distance(const vect2<T>& head, const Ts&... tail)
    -> std::enable_if_t<(std::is_base_of<vect2<T>, Ts>{} && ...), double>;

In :

#include <type_traits>
template <bool...>
struct bool_pack {};    
template <typename T, typename... Ts>
auto vect_distance(const vect2<T>& head, const Ts&... tail)
    -> std::enable_if_t<std::is_same<bool_pack<true, std::is_base_of<vect2<T>, Ts>{}...>,
                                     bool_pack<std::is_base_of<vect2<T>, Ts>{}..., true>
                                     >{}, double>;
Related