【发布时间】:2015-03-21 06:38:08
【问题描述】:
我有一个函数,我试图将其转换为使用可变参数模板。不幸的是,在编译期间尝试强类型函数时,模板扩展会导致问题。
这是旧代码:
std::unique_ptr<std::stringstream> Execute(CommandType command, ...) {
auto resp = std::make_unique<std::stringstream>();
va_list vl;
va_start(vl, command);
switch(command) {
case CommandType::Post:
*resp << Post(va_arg(vl, char *), va_arg(vl, char *));
break;
case CommandType::Get:
*resp << Get(va_arg(vl, char *));
break;
case CommandType::Delete:
*resp << Delete(va_arg(vl, char *), va_arg(vl, char *));
break;
}
va_end(vl);
return resp;
}
以及对应的功能:
bool Post(char *command, char *payload);
char *Get(char *command);
bool Delete(char *command, char *name);
理想情况下,我希望能够将其转换为类似以下内容的内容:
template< typename... Params>
std::unique_ptr<stringstream> Execute(CommandType command, Params... parameters) {
auto response = std::make_unique<stringstream>();
if(command == CommandType::Get)
response << Get(parameters);
else if(command == CommandType::Post)
response << Post(parameters);
else if(command == CommandType::Delete)
response << Delete(parameters);
else if(command == CommandType::OtherFunc)
response << OtherFunc(parameters);
return response;
};
bool Post(std::string command, std::string payload);
std:string Get(std::string command);
bool Delete(std::string command, std::string name);
int OtherFunc(std::string command, bool enabled, MyClass name);
- 此处添加了 OtherFunc 以获得更复杂的类型示例。
但这显然行不通,因为编译器认为每个命令都应该获取传递给模板的参数,而实际上只有一个基于 CommandType 的命令应该实际接收参数。
有什么技巧可以使用模板重写它并维护强类型,还是我必须使用 var args 和指针来保留它?
【问题讨论】:
-
顺便说一句,旧代码具有未定义的行为。您对
va_arg的调用不能保证以任何特定顺序发生——函数参数可以以任何顺序进行评估。我见过编译器出于各种异想天开的原因对它们进行重新排序,例如更改优化设置后。
标签: c++ templates variadic-templates