Установка значений Arduino String в классе - PullRequest
1 голос
/ 16 марта 2019

У меня есть объявление класса, которое я буду использовать много раз с разными значениями для заголовков и значений

class Generator
{
    public:
        String  Titles[9];     
        int16_t Values[9];
        byte    MainSel;
        void    SetTitles(String names[9])
                {
                    for (i = 0; i < 9; i++)
                        Titles[i] = names[i];
                }                   
        void    Update_Display()
                {
                    Display(__func__, Titles, Values, MainSel);
                }
};

Я объявляю его экземпляр и пытаюсь установить заголовки с помощью SetTitles

    Generator Organ_Levels;

    Organ_Levels.SetTitles("", "Rot", "Tone", "Sprd", "Bal", "Upper", "Lower", "Pedal", "Volume");

Но компилятор, кажется, думает, что я передаю массивы символов:

Нет соответствующей функции для вызова 'Generator :: SetTitles (const char [1], const char [4], const char [5], const char [5], const char [4], const char [6], const char [6], const char [6], const char [7]) '

Почемуразве они не воспринимаются как экземпляры типа Arduino String?

Ответы [ 3 ]

4 голосов
/ 16 марта 2019

Ваша функция SetTitles ожидает массив строк, но в этой строке:

  Organ_Levels.SetTitles("", "Rot", "Tone", "Sprd", "Bal", "Upper", "Lower", "Pedal", "Volume");

Вы вызываете функцию с 9 параметрами. определите массив, заполните его вашими данными, затем передайте его SetTitles:

string names[9]={"", "Rot", "Tone", "Sprd", "Bal", "Upper", "Lower", "Pedal", "Volume"};
    Organ_Levels.SetTitles(names);

и я должен отметить, что String не является типом c ++.

4 голосов
/ 16 марта 2019

Не ясно, что такое String, но я предполагаю, что оно будет похоже на std::string.

Передача массивов в качестве аргумента - ужасная идея. Вместо этого выберите вектор:

    void    SetTitles(vector<string> names)

После этого вы можете легко назвать это созданием вектора в потоке, добавив всего две фигурные скобки:

Organ_Levels.SetTitles({"", "Rot", "Tone", "Sprd", "Bal", "Upper", "Lower", "Pedal", "Volume"});    return 0;

Демоверсия

Еще один шаг вперед - это получить набор массива в вашем классе. Затем вы можете заменить цикл for, чтобы копировать значения одно за другим в простой оператор присваивания на векторном уровне.

2 голосов
/ 16 марта 2019

Если вы используете C ++ 11 или выше, вы могли бы вызывать SetTitles в качестве переменной функции (той, которой можно передать переменное число аргументов) с помощью пакетов параметров.

template<class ...Ts>
void SetTitles(Ts... args)    // accepts an arbitrary number of arguments
{
    std::vector<String> names {args...};   // unpacks the arguments into an initialiser list          
                                           // and constructs a vector with it

    const int size = std::min(9, names.size());     // size should be no bigger than 9      
                                                    //  to prevent undefined behaviour      
    // loop through the vector as normal
    for (int i = 0; i < size; i++)
        Titles[i] = names[i];
}

Это позволяет:

Organ_Levels.SetTitles("", "Rot", "Tone", "Sprd", "Bal", "Upper", "Lower", "Pedal", "Volume");

и даже больше:

Organ_Levels.SetTitles("p", "a", "r", "a", "m", "e", "t", "e", "r", " ", "p", "a", "c", "k", " ", "a", "b", "u", "s", "e");

Однако, поскольку Generator::Titles имеет размер, установленный на9, последний пример будет содержать не более 9 заголовков.Чтобы сделать это число динамическим, рассмотрите возможность изменения массива String Titles[] на std::vector (например, std::vector<String> Titles).Обратите внимание, что вам может потребоваться изменить и другие части кода (например, массив int16_t Values[]).Есть также дополнительное преимущество, заключающееся в том, что вы можете устранить цикл, непосредственно скопировав вектор:

template<class ...Ts>
void SetTitles(Ts... args)
{
    std::vector<String> names {args...};

    //  works if Titles is an std::vector
    Titles = names;
    //  Titles = std::vector<String>{args...}; // should also work
}

Благодаря подсказке Кристофа .

...