如何将一个或多个(未定义的数字)参数传递给函数

How to passing one or more (undefined number) parameters to a function?

本文关键字:数字 参数传递 函数 未定义 一个      更新时间:2023-10-16

我正在为wiringPi编写包装类。我希望能够通过将一个或多个参数传递给该函数来操纵多个LED,通过调用一次函数。传递的参数的数量不应受到限制,即可以是1、2、3或更多。这是我当前的功能:

typedef enum{LED1 = 12, LED2 = 13, LED3 = 14, LED4 = 15}LED;
void Led::on(LED led)
{
    digitalWrite(led, HIGH);
}

我可以这样做吗?以及如何?

我认为我可以为此使用过载,但是如果参数的数量不确定(即可以是1或7(?

bitfield?

如果您有少量的LED,并且使用不同位定义其值

typedef enum {LED1 = 1, LED2 = 2, LED3 = 4, LED4 = 8};

或更高(确保tu仅使用两个值的功率(,如用户2079303所建议(谢谢!(,

typedef enum {LED1 = 1 << 0, LED2 = 1 << 1, LED3 = 1 << 2, LED4 = 1 << 3};

您可以将LED值传递给Led::on()

on(LED1 | LED2 | LED4);

检查,在on()内,单位

void Led::on (int leds)
 {
   if ( 0 != (leds & LED1) )
    /* do something for LED1 */;
   if ( 0 != (leds & LED2) )
    /* do something for LED2 */;
   // ...
 }

使用variadic的示例。这可能是完成此操作的最有效方法,因为所有工作都是在编译时间内完成的。

enum LED {LED1 = 12, LED2 = 13, LED3 = 14, LED4 = 15};
constexpr const int HIGH = 1;
void digitalWrite(LED, int);
template<class... LED>
void on(LED... leds)
{
    (digitalWrite(leds, HIGH), ...);
}
void foo() {
    on(LED1, LED2, LED3);
    on(LED4);
}

https://godbolt.org/g/b22y5n

注意:您需要C 17对于上述语法


C 11兼容版本:

enum LED {LED1 = 12, LED2 = 13, LED3 = 14, LED4 = 15};
constexpr const int HIGH = 1;
void digitalWrite(LED, int);
void on(LED leds)
{
    digitalWrite(leds, HIGH);
}
template<class... LEDs>
void on(LED led, LEDs... leds)
{
    on(led);
    on(leds...);
}
void foo() {
    on(LED1, LED2, LED3);
    on(LED4);
    on(LED1, LED2);
}

https://godbolt.org/g/js13vi

对于均质的参数集合(即同一类型的对象(,在C 中执行此操作的惯用方法是传递一对迭代器。第一个迭代器到范围的开头,第二个迭代器到末端(确切地说是一个末端(。

尽管可以编写一个模板来处理所有输入迭代器,但一个简单的选择是支持一个特定的迭代器。迭代器的选择取决于您选择的数据结构来存储对象。例如,您可以使用指针参数支持数组:

void Led::on(LED* begin, LED* end)
{
    std::foreach(begin, end, [](auto& led) {
        digitalWrite(led, HIGH);
    }):
}

有几种方法可以完成此操作。

最琐碎的是使用上述评论中提到的std::vector

#include <vector>
void Led::on(std::vector<LED>) {
    for (LED l : leds) {
        digitalWrite(l, HIGH);
    }
}
std::vector<LED> leds = {LED1, LED2};
// you realize you need more
leds.push_back(LED3);
Led::on(leds);

您可以使用variadic functions。我不会推荐这一点也不会解释这一点。我已经提供了一个帮助您的链接。

您可以通过LED s的容器。例如使用std::initializer_list

typedef enum{LED1 = 12, LED2 = 13, LED3 = 14, LED4 = 15}LED;
void Led::on(std::initializer_list<LED>& leds)
{
    for (auto& led : leds) // Since this is tagged C++11
    {
        digitalWrite(led, HIGH);
    }
}

调用此功能将很简单:

Led::on({LED1, LED2, LED3});

使用初始化列表很不错,因为它轻巧且易于使用。这是一个最小的工作示例。