[英]Attempt at mimicking the python print function using variadic templates not working
I came across variadic template s while reading a book and thought it would be pretty cool to implement a python style print
function.我在看书时遇到了variadic template ,并认为实现 python 风格的
print
功能会很酷。
Here is the code.这是代码。
#include <iostream>
#include <string>
#define None " "
template<typename T, typename... Tail>
void print(T head, Tail... tail, const char* end = "\n")
{
std::cout << head << end;
if constexpr (sizeof...(tail) > 0)
{
print(tail..., end);
}
}
int main()
{
// Error: no instance of function template "print" matches the argument list
print("apple", 0, 0.0f, 'c', true);
// Error: no instance of function template "print" matches the argument list
print("apple", 0, 0.0f, 'c', true, None);
}
Expected result from those two function calls:这两个函数调用的预期结果:
First: Second:
apple apple 0 0.0f 'c' 1
0
0.0f
'c'
1
Removing const char* end = "\\n"
from the function signature gets the code to compile, but I want that functionality of specifying the last parameter to state whether to print a newline.从函数签名中删除
const char* end = "\\n"
获取要编译的代码,但我希望指定最后一个参数来说明是否打印换行符的功能。
Is this possible at all?这可能吗?
It is possible, but not in the way you have tried.这是可能的,但不是您尝试过的方式。
You could do something like the following (one possible solution in c++17 ):您可以执行以下操作( c++17 中的一种可能解决方案):
Ending
) which will be used to specify the way of printing (ie newline, with space, etc).Ending
),用于指定打印方式(即换行、空格等)。print
and one of them will be used to print one argument at a time, where we will check for the way of printing;print
,其中一个将用于一次打印一个参数,我们将在其中检查打印方式;print
will be used to call the variadic arguments by the caller.print
将用于调用者调用 可变参数。 Here we're using fold expressions to call the first print
overload.print
重载。 Something like: ( Live Demo )类似于:(现场演示)
enum struct Ending { NewLine = 0, Space };
template<Ending end, typename Type>
void print(const Type& arg) noexcept
{
if constexpr (end == Ending::NewLine) {
std::cout << arg << '\n';
}
else if constexpr (end == Ending::Space) {
std::cout << arg << ' ';
}
}
template <Ending end, typename... Args>
void print(const Args& ... args) noexcept
{
(print<end>(args), ...);
}
Now you can specify, how to end the line现在您可以指定如何结束该行
print<Ending::NewLine>("apple", 0, 0.0f, 'c', true);
print<Ending::Space>("apple", 0, 0.0f, 'c', true);
"You don't like the overload!?" “你不喜欢超载!?” Then we can make it inside a single
print
function with help of an immediately invoking lambda function.然后我们可以在立即调用 lambda 函数的帮助下将其放入单个
print
函数中。
template <Ending end, typename... Args>
void print(const Args& ... args) noexcept
{
([] (Ending, const auto& arg) noexcept {
if constexpr (end == Ending::NewLine) {
std::cout << arg << '\n';
}
else if constexpr (end == Ending::Space) {
std::cout << arg << ' ';
}
}(end, args), ...);
//^^^^^^^^^^ ^^^^ ---> Invoke the lambda & expand the fold
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.