有没有办法为递归函数部分特化带有参数包的模板?
Is there a way to partially specialize a template with parameter packs for a recursive function?
我正在尝试在 C++
中创建一个打印函数,它接收可变数量的参数并将它们打印在各自的行中,例如:
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
std::cout << cur_line << '\n';
println(other_lines);
}
void println() { std::cout << std::flush; }
但是,如果 Ty
恰好是 std::vector<std::string>
,我想以不同的方式对待它(因为我想在自己的行上打印矢量的每个元素)。我研究了部分专业化,但在使用参数包这样做时,我似乎找不到太多东西。这是我尝试过的:
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
std::cout << cur_line << '\n';
println(other_lines);
}
template<typename... Types>
void println<std::vector<std::string>, Types...>
(std::vector<std::string> cur_line, Types... other_lines)
{
for (const auto& line : cur_line)
{
std::cout << line << '\n';
}
println(other_lines);
}
void println() { std::cout << std::flush; }
但是,我收到 MSVC 错误 C2768:“'println': illegal use of explicit template arguments
”。
任何建议或解决方案都将受到热烈欢迎!作为参考,我使用的是 Visual Studio 2019 Preview 及其相应的编译器版本。
一种更简单的方法是使用打印函数并重载:
template < typename T >
void print(const T& line)
{
std::cout << line << '\n';
}
template < typename T >
void print(const std::vector<T>& line)
{
for (const auto& element : line)
{
print(element);
}
}
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
print(cur_line);
println(other_lines);
}
void println() { std::cout << std::flush; }
您不能部分特化函数模板,但可以重载它。创建一个 println
的新重载,它将 std::vector<std::string>
作为第一个参数,将通用包作为其余参数。然后对向量 arg 进行特殊处理,并像以前一样转发其余部分。现在你的向量总是会被过载捕获。
你可以这样做:
/* main.cpp */
#include <iostream>
#include <vector>
#include <string>
using namespace std;
template <class T>
void PrintLine(const T &t)
{
cout << t << endl ;
}
template <class T>
void PrintLine(const vector<T> &t)
{
for(auto &obj : t ) PrintLine(obj);
}
template <class ... TT>
void PrintLines(const TT & ... tt)
{
( PrintLine(tt) , ... );
}
/* main() */
int main()
{
vector<string> list{"a","b","c"};
PrintLines(1,2,3,list);
return 0;
}
我正在尝试在 C++
中创建一个打印函数,它接收可变数量的参数并将它们打印在各自的行中,例如:
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
std::cout << cur_line << '\n';
println(other_lines);
}
void println() { std::cout << std::flush; }
但是,如果 Ty
恰好是 std::vector<std::string>
,我想以不同的方式对待它(因为我想在自己的行上打印矢量的每个元素)。我研究了部分专业化,但在使用参数包这样做时,我似乎找不到太多东西。这是我尝试过的:
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
std::cout << cur_line << '\n';
println(other_lines);
}
template<typename... Types>
void println<std::vector<std::string>, Types...>
(std::vector<std::string> cur_line, Types... other_lines)
{
for (const auto& line : cur_line)
{
std::cout << line << '\n';
}
println(other_lines);
}
void println() { std::cout << std::flush; }
但是,我收到 MSVC 错误 C2768:“'println': illegal use of explicit template arguments
”。
任何建议或解决方案都将受到热烈欢迎!作为参考,我使用的是 Visual Studio 2019 Preview 及其相应的编译器版本。
一种更简单的方法是使用打印函数并重载:
template < typename T >
void print(const T& line)
{
std::cout << line << '\n';
}
template < typename T >
void print(const std::vector<T>& line)
{
for (const auto& element : line)
{
print(element);
}
}
template<typename Ty, typename... Types>
void println(Ty cur_line, Types... other_lines)
{
print(cur_line);
println(other_lines);
}
void println() { std::cout << std::flush; }
您不能部分特化函数模板,但可以重载它。创建一个 println
的新重载,它将 std::vector<std::string>
作为第一个参数,将通用包作为其余参数。然后对向量 arg 进行特殊处理,并像以前一样转发其余部分。现在你的向量总是会被过载捕获。
你可以这样做:
/* main.cpp */
#include <iostream>
#include <vector>
#include <string>
using namespace std;
template <class T>
void PrintLine(const T &t)
{
cout << t << endl ;
}
template <class T>
void PrintLine(const vector<T> &t)
{
for(auto &obj : t ) PrintLine(obj);
}
template <class ... TT>
void PrintLines(const TT & ... tt)
{
( PrintLine(tt) , ... );
}
/* main() */
int main()
{
vector<string> list{"a","b","c"};
PrintLines(1,2,3,list);
return 0;
}