C++ Как передать в функцию разное количество параметров
Есть конструктор Simple_value, который принимает название фигуры и любое кол-во точек. В векторе _Temp_points_for_centroid_points у меня хранятся 4 или 8 точек для разных фигур.
if(Tetrahedron)
_Centroid_value = Simple_value(Tetrahedron,
_Temp_points_for_centroid_points[0],
_Temp_points_for_centroid_points[1],
_Temp_points_for_centroid_points[2],
_Temp_points_for_centroid_points[3]);
if(Prism)
_Centroid_value = Simple_value(Prism,
_Temp_points_for_centroid_points[0],
_Temp_points_for_centroid_points[1],
_Temp_points_for_centroid_points[2],
_Temp_points_for_centroid_points[3],
_Temp_points_for_centroid_points[4],
_Temp_points_for_centroid_points[5],
_Temp_points_for_centroid_points[6],
_Temp_points_for_centroid_points[7]);
Можно ли сделать какой-то макрос (или что-то другое), чтобы я упростил конструкцию до
#define ALL_NODES(num) _Temp_points_for_centroid_points[0], ..., _Temp_points_for_centroid_points[num - 1]
_Centroid_value = Simple_value(Tetrahedron, ALL_NODES(4));
Т.к. количество точек в векторе всегда известно. Поменять конструктор, чтобы он принимал не точки, а весь вектор - нет возможности.
Ответы (3 шт):
Автор решения: KoVadim
→ Ссылка
Может написать что то вида ?
MyCentroid Get(vector<...> _Temp_points_for_centroid_points)
{
if (_Temp_points_for_centroid_points.length() == 4)
return Simple_value(Tetrahedron,
_Temp_points_for_centroid_points[0],
_Temp_points_for_centroid_points[1],
_Temp_points_for_centroid_points[2],
_Temp_points_for_centroid_points[3]);
if (_Temp_points_for_centroid_points.length() == 8)
return Simple_value(Prism,
_Temp_points_for_centroid_points[0],
_Temp_points_for_centroid_points[1],
_Temp_points_for_centroid_points[2],
_Temp_points_for_centroid_points[3],
_Temp_points_for_centroid_points[4],
_Temp_points_for_centroid_points[5],
_Temp_points_for_centroid_points[6],
_Temp_points_for_centroid_points[7]);
///.....
}
Автор решения: dIm0n
→ Ссылка
Примерно вот так для конструкторов с 4 и 8 точками:
#include <iostream>
#include <cstddef>
#include <vector>
#include <utility>
#include <tuple>
struct Monster {
Monster(int p1, int p2, int p3, int p4) {
std::cout << "4 points:\n"
<< p1 << ' ' << p2 << ' ' << p3 << ' ' << p4
<< '\n';
}
Monster(int p1, int p2, int p3, int p4,
int p5, int p6, int p7, int p8) {
std::cout << "8 points:\n"
<< p1 << ' ' << p2 << ' ' << p3 << ' ' << p4
<< '\n'
<< p5 << ' ' << p6 << ' ' << p7 << ' ' << p8
<< '\n';
}
};
template<typename T, std::size_t... indices>
auto generate_tuple(const std::vector<T>& v, std::index_sequence<indices...>) {
return std::tuple{v[indices]...};
}
template<std::size_t N, typename T>
auto vector_to_tuple(const std::vector<T>& v) {
return generate_tuple(v, std::make_index_sequence<N>());
}
int main() {
std::vector tetrahedron = {1, 2, 3, 4};
std::vector prism = {1, 2, 3, 4, 5, 6, 7, 8};
constexpr auto monster_generator = [](auto&&... args) {
return Monster{std::forward<decltype(args)>(args)...};
};
const auto m1 = std::apply(monster_generator, vector_to_tuple<4>(tetrahedron));
const auto m2 = std::apply(monster_generator, vector_to_tuple<8>(prism));
}
Автор решения: Croessmah
→ Ссылка
Не зная конструкторов Simple_value и того, что такое Tetrahedron и Prism, могу предложить такое решение:
#include <utility>
template<typename T>
constexpr size_t points_count = 0;
#define REGISTER_TYPE_TAG(Tag, Count) \
template<> constexpr size_t points_count<struct Tag> = Count
REGISTER_TYPE_TAG(TetrahedronTag, 4);
REGISTER_TYPE_TAG(PrismTag, 8);
template<typename ... Ts, size_t ... Indexes>
Simple_value create_simple_value_impl(std::vector<YourPointType> const & points, std::index_sequence<Indexes...>, Ts && ... args)
{
return Simple_value(std::forward<Ts>(args)..., points[Indexes]...);
}
template<typename TypeTag, typename ... Ts>
Simple_value create_simple_value(std::vector<YourPointType> const & points, Ts && ... args)
{
static_assert(points_count<TypeTag> != 0, "invalid tag");
return create_simple_value_impl(points, std::make_index_sequence<points_count<TypeTag>>(), std::forward<Ts>(args)...);
}
//...
if(Tetrahedron)
_Centroid_value = create_simple_value<TetrahedronTag>(_Temp_points_for_centroid_points, Tetrahedron);
if(Prism)
_Centroid_value = create_simple_value<PrismTag>(_Temp_points_for_centroid_points, Prism);