xml*_*lmx 9 c++ templates overloading overload-resolution c++17
#include <iostream>
template<typename... Args>
void print(Args const&... args)
{
(std::cout << ... << args);
}
int main()
{
std::cout << 1 << 2 << 3 << std::endl; // ok
print(1, 2, 3); // ok
print(1, 2, 3, std::endl); // error! How to make it work?
}
Run Code Online (Sandbox Code Playgroud)
看在线演示
如何将函数模板作为模板参数传递?
for*_*818 10
对于其他 io 操作器,当它们是模板时,您将遇到相同的问题,这些操作器通常是将流作为参数的函数。尽管您可以将它们包装在非模板可调用中:
#include <iostream>
template<typename... Args>
void print(Args const&... args)
{
(std::cout << ... << args);
}
int main()
{
std::cout << 1 << 2 << 3 << std::endl; // ok
print(1, 2, 3); // ok
print(1, 2, 3, [](std::ostream& o) -> std::ostream&{
o << std::endl;
return o;
}); // no error!
}
Run Code Online (Sandbox Code Playgroud)
输出:
123
123123
Run Code Online (Sandbox Code Playgroud)
语法相当繁重,因此您可能想要使用辅助类型,尽管我将其留给您来编写(只是开玩笑,我认为这不是微不足道的,但我可能会稍后尝试;)。经过一段时间的思考,我几乎可以肯定只有两种选择:实例化函数(参见其他答案),或者将调用包装在 lambda 中,除非您想为每个单个 io 操纵器编写一个包装器课程。
这里有一个方法:
print(1, 2, 3, std::endl<char, std::char_traits<char>>);
Run Code Online (Sandbox Code Playgroud)
考虑'\n'改用。
您不能获取大多数标准函数的地址(请参阅can-i-take-the-address-of-a-function-defined-in-standard-library)。
幸运的是,io-manipulator 是例外的一部分(参见Addressable_functions)。
std::endl 是模板函数,因此您必须选择正确的重载。
using print_manip_t = std::ostream& (*) (std::ostream&);
print(1, 2, 3, print_manip_t{std::endl});
print(1, 2, 3, static_cast<print_manip_t>(std::endl));
print(1, 2, 3, static_cast<std::ostream& (*) (std::ostream&)>(std::endl));
Run Code Online (Sandbox Code Playgroud)
否则你必须指定你想要的
print(1, 2, 3, std::endl<char, std::char_traits<char>>);
Run Code Online (Sandbox Code Playgroud)
或包裹它
print(1, 2, 3, [](std::ostream& o) -> std::ostream&{ return o << std::endl; });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
155 次 |
| 最近记录: |