rat*_*der 7 c++ macros templates c++11
我偶然发现了看起来像这样的旧代码:
void dothing(bool testBool,
const std::string& testString1,
const std::string& file,
int line,
const std::string& defaultString = "")
{
// do something...
}
void dothings(bool testBool,
const std::string& testString1,
const std::string& testString2,
const std::string& file,
int line,
const std::string& defaultString = "")
{
dothing(testBool, testString1, file, line, defaultString);
dothing(testBool, testString2, file, line, defaultString);
}
void dothings(bool testBool,
const std::string& testString1,
const std::string& testString2,
const std::string& testString3,
const std::string& file,
int line,
const std::string& defaultString = "")
{
dothings(testBool, testString1, testString2, file, line, defaultString);
dothing(testBool, testString3, file, line, defaultString);
}
void dothings(bool testBool,
const std::string& testString1,
const std::string& testString2,
const std::string& testString3,
const std::string& testString4,
const std::string& file,
int line,
const std::string& defaultString = "")
{
dothings(testBool, testString1, testString2, testString3, file, line, defaultString);
dothing(testBool, testString1, file, line, defaultString);
}
Run Code Online (Sandbox Code Playgroud)
这很荒谬,我试图将其重构为:
void dothings(bool testBool,
std::initializer_list<std::string> testStrings,
const std::string& file,
int line,
const std::string& defaultString = "")
{
for(auto iter = testStrings.begin(); iter != testStrings.end(); ++iter)
{
dothing(testBool, *iter, file, line, defaultString);
}
}
Run Code Online (Sandbox Code Playgroud)
问题是这些函数被大量使用,我想编写一个宏或模板,以便所有以前的函数构造所有测试字符串的字符串的初始化列表,并将它们传递给一个新函数.我想写这样的东西:
#define dothings(testBool, (args), file, line) dothings(testBool, {args}, file, line)
Run Code Online (Sandbox Code Playgroud)
我并不关心这些函数中的默认字符串,但是如果有办法支持它,那就太棒了.
我可以访问c ++ 11编译器并仅提升.
我无法重新排序这些函数的参数.
我看过一些关于变量参数宏的有趣帖子,但它并没有点击如何将它们应用于这种情况.
这只是可能的解决方案之一,可以改进以检测最后是否存在额外的默认字符串(通过一些其他元编程技术与SFINAE一起).这个利用索引技巧将参数列表分成两个子序列:一个用于三个尾随参数,一个用于字符串本身.最终,每个串搭配的其余参数与调用函数dothing的扩展.
void dothing(bool testBool
, const std::string& str
, const std::string& file
, int line
, const std::string& defaultString)
{
// processing of a single str
}
template <typename... Args, std::size_t... Is>
void dothings(bool testBool, std::index_sequence<Is...>, Args&&... args)
{
auto tuple = std::make_tuple(std::forward<Args>(args)...);
using expander = int[];
static_cast<void>(expander{ 0, (dothing(testBool, std::get<Is>(tuple)
, std::get<sizeof...(Args)-3>(tuple)
, std::get<sizeof...(Args)-2>(tuple)
, std::get<sizeof...(Args)-1>(tuple)), 0)... });
}
template <typename... Args>
void dothings(bool testBool, Args&&... args)
{
dothings(testBool
, std::make_index_sequence<sizeof...(Args)-3>{}
, std::forward<Args>(args)...);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
226 次 |
| 最近记录: |