我可以区分一个或多个参数吗?
Can I differentiate between one and multiple arguments?
C++11 或 C++14 中是否有任何新功能可以让我们停止使用:
TRACE0("one-string-no-args");
和
TRACE("formatting string with one-or-more args", arg1, arg2, etc);
这些函数必须通过名称进行区分,因为据我所知,重载无法区分零附加参数情况和一个或多个参数情况。
这当然对printf
样式接口很重要,在这种接口中,能够知道不再有参数意味着您可以通过不尝试将格式化字符串解释为格式化字符串,而仅将其解释为最终输出字符串来避免一类错误。
您可能只是不知道该功能的名称:可变参数模板。
它的主要用途是从可变数量的参数中推导出可变数量的类型;你可以将它们全部存储在某个地方(如std::make_tuple()
(,或者只是打开参数来使用它们。
下面是一个基本用法:
void print() {}
template<class Head, class... Tail>
void print(Head h, Tail... t)
{
cout << h << endl;
print(t...);
}
int main()
{
print(3, "hello", 4.5);
}
在这里看到它的实际效果: http://ideone.com/VA7YGK
正如你所看到的,它看起来像函数式编程(因为它是!(,你匹配一个规则,将参数列表分成一个头和一个尾,然后用一个少一个元素调用自身。
另一个例子,来自最近的一个问题,我递归地定义了一个数据结构(简短而简单,可以阅读(: 使用可变参数模板的多键映射
std::thread
构造函数是另一个例子,一旦函数开始在生成的线程中运行,它就需要可变数量的参数将它们提供给函数;C++11 中几乎所有与函数交互的新内容(例如 std::function
( 使用可变参数模板,因此它们可以接受任意数量的任何类型的参数。 std::tuple
,std::make_tuple()
和std::tie()
也使用它。
搜索网络,你会发现很多更高级的用法。特别注意参数扩展和完善转发的规则。
对于TRACE
宏(通常包含在Microsoft的调试宏中(,不,该语言将没有处理预处理器宏的"新"方法(它实际上与以前相同(。
对于一般的函数,一直支持可变参数函数(例如 printf
(。
这对某些人来说似乎很愚蠢 - 但我有一公吨的 C 风格的 printf 代码需要维护。
我们可以使用 boost 的格式库重建这一切,也许有一天我们会得到它。 然而,与此同时,仅仅能够区分一个论点,或者一个+一个或多个论点,就是向前迈出的一大步。
https://stackoverflow.com/users/365496/bames53 指出这是可能的,并且它似乎有效(在代码膨胀中可能付出一些代价,并且需要注意的是,这仍然是 printf 土地及其所有陷阱(。
下面是一个简单的示例,可以在 MFC/C++ 中完成它的工作:
bool Write(const wchar_t * pszText);
template <typename T> bool Write(const wchar_t * pszFormat, T, ...);
Write 不需要(也不应该(调用 vwsprintf 等效项,而 Write<> 这样做是为了在将输出字符串传递给 Write 之前构建输出字符串。
非常优雅。 消除了仅提供第二个接口的问题(然后,如果您的一个字符串碰巧有一个意外的 printf 格式说明符,则会遇到 printf 问题(,或者强制客户端指定 Write(( 与 WriteFormat(( 或在调用 Write(( 之前在本地进行类似的字符串构造。
下面是 Write<>根据 Write 定义:
template <typename T> bool SimpleTextFile::Write(const wchar_t * pszFormat, T, ...)
{
va_list arglist;
va_start(arglist, pszFormat);
CStringW buffer;
buffer.FormatV(pszFormat, arglist);
va_end(arglist);
return Write(buffer);
}
- 如果需要转换,我可以在读取参数的同时将其移动到另一个参数吗?
- 我可以使用宏自动构建参数列表吗?
- 我可以在类中存储构造函数的模板参数吗?
- 我可以动态创建新地图并作为函数参数传递吗?
- 我可以在模板参数扣除期间获得转换吗?
- 我可以用clang AST从模板专业化中获得默认的模板参数吗
- C++:我可以在模板参数包中强制执行至少1个agment吗
- 我可以std::在fold表达式中转发参数吗
- 我可以将"token pasting operator"与"const"模板参数一起使用吗?
- 我可以将函数的输出参数存储到unique_ptr中吗?
- 我可以有条件地使用多个参数吗?
- 我可以更改将引用参数传递到指针中并使其正常工作的函数的输入(C、C++)吗?
- 我可以防止参数隐式转换为赋值运算符吗?
- 我可以通过命令行参数传递给C++程序多少数据?
- 我可以在模板参数中声明一个 constexpr lambda 吗?
- 我可以在哪里放置参数的默认值
- 我可以将模板中的类型参数用于非类型参数吗?
- 我可以指定或选择类的成员(并将其用作参数)吗?
- 带有容器和默认分配器的模板模板参数:我可以让我的声明更紧凑吗
- 可变模板参数:我可以根据类型选择引用还是值