Nik*_*ock 1 c++ templates metaprogramming variadic-templates
想象一下我有两个功能:
void string(const char *str)
{
std::cout << "this is string" << std::endl;
}
void number(const char *str, double f)
{
std::cout << "this is number" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
我想编写一个通用包装器,以便能够format()像这样调用:
int main() {
format("single arg");
format("format string", 1.0);
format("single arg", "format string", 1.0);
format("format string 1", 1.0, "just string arg", "format string 2", 2.0);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
也就是说,如果参数以 {string, number} 对的形式出现,则调用number(); 否则请致电string(). 显然,只能从右到左解包参数。我尝试按照以下(错误)方式实现它:
template<class T>
void operation(T first)
{
string(first);
}
template<class T, class U = float>
void operation(T first, U second)
{
number(first, second);
}
template<class ... ARGS>
void format(ARGS ... args)
{
auto last = (args, ...);
using last_type = typename decltype(last);
if constexpr (std::is_arithmetic_v<last_type>)
(..., operation(args, last));
else
(..., operation(args));
}
Run Code Online (Sandbox Code Playgroud)
问题是,在打开包装时,operation(args, last)我们会同时得到args和last漂浮物。我相信有一些简单的方法可以实现我想要的(不依赖元组等)。
这是仅使用重载解析的概念验证。不过,我不确定它的可扩展性如何。
void format() {}
void format(char const *str) {
string(str);
}
template <class... Args>
void format(char const *str, char const *nextStr, Args... args);
template <class... Args>
void format(char const *str, double f, Args... args);
template <class... Args>
void format(char const *str, char const *nextStr, Args... args) {
string(str);
format(nextStr, args...);
}
template <class... Args>
void format(char const *str, double f, Args... args) {
number(str, f);
format(args...);
}
Run Code Online (Sandbox Code Playgroud)