我怎么能写一个函数,接受可变数量的参数?这可能吗?怎么可能?
当前回答
在c++ 11中,有一种方法可以创建变量参数模板,从而以一种非常优雅且类型安全的方式来使用变量参数函数。Bjarne自己在c++ 11FAQ中给出了一个使用变量参数模板的printf的好例子。
就我个人而言,我认为这是如此优雅,以至于在编译器支持c++ 11变量参数模板之前,我甚至不会为c++中的变量参数函数而烦恼。
其他回答
支持彩色代码的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++ 11中,有一种方法可以创建变量参数模板,从而以一种非常优雅且类型安全的方式来使用变量参数函数。Bjarne自己在c++ 11FAQ中给出了一个使用变量参数模板的printf的好例子。
就我个人而言,我认为这是如此优雅,以至于在编译器支持c++ 11变量参数模板之前,我甚至不会为c++中的变量参数函数而烦恼。
可能你想重载或默认参数-用默认参数定义相同的函数:
void doStuff( int a, double termstator = 1.0, bool useFlag = true )
{
// stuff
}
void doStuff( double std_termstator )
{
// assume the user always wants '1' for the a param
return doStuff( 1, std_termstator );
}
这将允许你用四种不同的调用之一来调用该方法:
doStuff( 1 );
doStuff( 2, 2.5 );
doStuff( 1, 1.0, false );
doStuff( 6.72 );
…或者你可以从C中寻找v_args调用约定。
int fun(int n_args, ...) {
int *p = &n_args;
int s = sizeof(int);
p += s + s - 1;
for(int i = 0; i < n_args; i++) {
printf("A1 %d!\n", *p);
p += 2;
}
}
普通的版本
除了可变参数或重载,你可以考虑将参数聚合在std::vector或其他容器中(例如std::map)。就像这样:
template <typename T> void f(std::vector<T> const&);
std::vector<int> my_args;
my_args.push_back(1);
my_args.push_back(2);
f(my_args);
通过这种方式,您将获得类型安全,并且这些可变参数的逻辑含义将是显而易见的。
当然,这种方法可能会有性能问题,但您不必担心,除非您确定无法为此付出代价。它是c++的一种“Pythonic”方法…
推荐文章
- 如何构建和使用谷歌TensorFlow c++ api
- 断言是邪恶的吗?
- 下面这些短语在c++中是什么意思:0 -,default-和value-initialization?
- 在STL地图中,使用map::insert比[]更好吗?
- C++ Linux的想法?
- 如何为Fedora安装g++ ?
- Std::cin输入空格?
- c++标准是否要求iostreams的性能很差,或者我只是在处理一个糟糕的实现?
- gcc在哪里查找C和c++头文件?
- 为什么我们需要require require ?
- 解析c++中的命令行参数?
- 我如何在c++中创建一个随机的字母数字字符串?
- c++中的atan和atan2有什么区别?
- 现代c++能让你免费获得性能吗?
- 一门语言是如何自我扩展的?