Есть ли способ оптимизировать/уменьшить эту последовательность присвоения переменных? (C )

#c #reduce

Вопрос:

Мне было интересно, есть ли способ оптимизировать/уменьшить эту логику? По мере увеличения числа переменных увеличивается и количество параметров, что может сделать код немного запутанным.

файл .h

 class ClassA
{
public:
    ClassB type1_1;
    ClassB type1_2;
    ClassB type1_3;
    // ... There can be more than this

    ClassB type2_1;
    ClassB type2_2;
    ClassB type2_3;
    // ... There can be more than this

    void SetType1(ClassB a, ClassB b, ClassB c);
    void SetType2(ClassB a, ClassB b, ClassB c);

    __forceinline vector<ClassB> GetListofType1() { return list_type1; }
    __forceinline vector<ClassB> GetListofType2() { return list_type2; }

private:
    vector<ClassB> list_type1;
    vector<ClassB> list_type2;
};
 

файл .cpp

 // ... As the number of type1 variables increases, the number of parameters increases
void ClassA::SetType1(ClassB a, ClassB b, ClassB c)
{
    type1_1 = a;
    type1_2 = b;
    type1_3 = c;

    list_type1.push_back(a);
    list_type1.push_back(b);
    list_type1.push_back(c);
}

// ... As the number of type2 variables increases, the number of parameters increases
void ClassA::SetType2(ClassB a, ClassB b, ClassB c)
{
    type2_1 = a;
    type2_2 = b;
    type2_3 = c;

    list_type2.push_back(a);
    list_type2.push_back(b);
    list_type2.push_back(c);
}
 

Комментарии:

1. Почему у вас есть 2 копии одного и того же объекта? Зачем вам нужно и type1_1 то, и другое, и list_type1[0] иметь дубликаты данных?

2. Есть ли какая-то особая причина, по которой вы не принимаете аргументы функции по ссылке?

3. Кроме того, ваша программа будет лучше обслуживаться, если вы передадите экземпляры ClassB по ссылке вместо значения в своих SetType функциях.

4. Это немного сложно. Вопрос в том, есть ли способ уменьшить эту логику? Особенно уменьшение количества параметров.

5. Это упрощенная версия реального кода. Я забыл добавить ссылочный символ, но в коде я отправляю их со ссылками

Ответ №1:

Использовать списки инициализаторов:

 #include <cassert>
#include <vector>

struct ClassB { };

class ClassA {
public:
  static constexpr int list_type1_len = 3;

  inline void SetType1(const std::vector<ClassB>amp; set_type_1){
      assert(set_type_1.size()==3);
      list_type1 = set_type_1;
  }

  inline std::vector<ClassB>amp; GetListofType1() { return list_type1; }

private:
  std::vector<ClassB> list_type1;
};


int main(){
    ClassA a;
    a.SetType1({ClassB(), ClassB(), ClassB()});

    return 0;
}
 

Ответ №2:

Если количество элементов известно во время компиляции, вы можете решить проблему дублирования кода с помощью шаблонов variadic и tuple s или array s.

Например:

 #include <iostream>
#include <array>

template <typename T, unsigned N1, unsigned N2>
class ClassA {
public:
  std::array<std::array<T,N2>,N1> xs { };

  template <unsigned N, typename... X>
  void SetType(Xamp;amp;... x) {
    std::get<N>(xs) = { std::forward<X>(x)... };
  }

  template <unsigned I1, unsigned I2>
  Tamp; get() {
    return std::get<I2>(std::get<I1>(xs));
  }
};

int main(int argc, char* argv[]) {
  ClassA<int,2,3> a;

  a.SetType<0>(1,2,3);

  std::cout << a.get<0,1>() << std::endl;
}