我怎么能写一个函数,接受可变数量的参数?这可能吗?怎么可能?


当前回答

在c++11中,你可以做:

void foo(const std::list<std::string> & myArguments) {
   //do whatever you want, with all the convenience of lists
}

foo({"arg1","arg2"});

列表初始化项FTW!

其他回答

支持彩色代码的c++ 11

是通用的,适用于所有数据类型 类似JavaScript console.log(1,"23") 支持颜色代码的信息,警告,错误。 例子:

#pragma once
#include <iostream>
#include <string>

const std::string RED = "\e[0;91m";
const std::string BLUE = "\e[0;96m";
const std::string YELLOW = "\e[0;93m";

class Logger {
private:
  enum class Severity { INFO, WARN, ERROR };

  static void print_colored(const char *log, Severity severity) {
    const char *color_code = nullptr;

    switch (severity) {
    case Severity::INFO:
      color_code = BLUE.c_str();
      break;
    case Severity::WARN:
      color_code = YELLOW.c_str();
      break;
    case Severity::ERROR:
      color_code = RED.c_str();
      break;
    }

    std::cout << "\033" << color_code << log << "\033[0m -- ";
  }

  template <class Args> static void print_args(Args args) {
    std::cout << args << " ";
  }

public:
  template <class... Args> static void info(Args &&...args) {
    print_colored("[INFO] ", Severity::INFO);
    int dummy[] = {0, ((void)print_args(std::forward<Args>(args)), 0)...};
    std::cout << std::endl;
  }

  template <class... Args> static void warn(Args &&...args) {
    print_colored("[WARN] ", Severity::WARN);
    int dummy[] = {0, ((void)print_args(std::forward<Args>(args)), 0)...};
    std::cout << std::endl;
  }

  template <class... Args> static void error(Args &&...args) {
    print_colored("[ERROR]", Severity::ERROR);
    int dummy[] = {0, ((void)print_args(std::forward<Args>(args)), 0)...};
    std::cout << std::endl;
  }
};

正如其他人所说,c风格的变量。但是你也可以对默认参数做类似的事情。

你可能不应该这样做,你可以用一种更安全、更简单的方式做你想做的事情。从技术上讲,要在C语言中使用可变数量的参数,需要包含stdarg.h。由此,您将获得va_list类型以及对其进行操作的三个函数va_start()、va_arg()和va_end()。

#include<stdarg.h>

int maxof(int n_args, ...)
{
    va_list ap;
    va_start(ap, n_args);
    int max = va_arg(ap, int);
    for(int i = 2; i <= n_args; i++) {
        int a = va_arg(ap, int);
        if(a > max) max = a;
    }
    va_end(ap);
    return max;
}

要我说,这真是一团糟。它看起来很糟糕,不安全,而且充满了与你在概念上试图实现的目标无关的技术细节。相反,可以考虑使用重载或继承/多态性、构建器模式(如流中的操作符<<())或默认参数等。这些都是更安全的:编译器会更多地了解你要做什么,这样就有更多的机会在你断腿之前阻止你。

c++ 17解决方案:完全类型安全+良好的调用语法

由于在c++ 11中引入了变进模板,在c++ 17中引入了fold表达式,因此可以在调用端定义一个模板函数,它可以像一个变进函数一样被调用,但优点是:

强类型安全; 在不使用参数数量的运行时信息或不使用“stop”参数的情况下工作。

下面是一个混合参数类型的例子

template<class... Args>
void print(Args... args)
{
    (std::cout << ... << args) << "\n";
}
print(1, ':', " Hello", ',', " ", "World!");

另一个对所有参数强制类型匹配:

#include <type_traits> // enable_if, conjuction

template<class Head, class... Tail>
using are_same = std::conjunction<std::is_same<Head, Tail>...>;

template<class Head, class... Tail, class = std::enable_if_t<are_same<Head, Tail...>::value, void>>
void print_same_type(Head head, Tail... tail)
{
    std::cout << head;
    (std::cout << ... << tail) << "\n";
}
print_same_type("2: ", "Hello, ", "World!");   // OK
print_same_type(3, ": ", "Hello, ", "World!"); // no matching function for call to 'print_same_type(int, const char [3], const char [8], const char [7])'
                                               // print_same_type(3, ": ", "Hello, ", "World!");
                                                                                              ^

更多信息:

可变参数模板,也称为参数包(自c++ 11起)- cppreference.com。 折叠表达式(自c++ 17开始) 查看coliru上的完整程序演示。

c++支持C风格的变进函数。

然而,大多数c++库使用另一种习惯,例如,' C ' printf函数接受变量参数,而c++ cout对象使用<<重载来解决类型安全和adt(可能以实现简单性为代价)。