首页 > 解决方案 > 如何将函数模板作为模板参数传递?

问题描述

#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?
}

在线演示

如何将函数模板作为模板参数传递?

标签: c++templatesc++17overloadingoverload-resolution

解决方案


当其他 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!
}

输出

123
123123

语法相当繁重,因此您可能想要使用辅助类型,尽管我将把它留给您来编写(只是开玩笑,我认为这不是微不足道的,但我以后可能会尝试一下;)。在思考了一会儿之后,我几乎可以肯定只有两种选择:实例化函数(参见其他答案),或者将调用包装在 lambda 中,除非您想为每个 io 操纵器编写一个包装器课程。


推荐阅读