【发布时间】:2021-09-03 14:38:28
【问题描述】:
在我发布的 answer 到 another question 中,Jack Harwood 分享了一个很好的解决方案,可以使用概念检测空的可变参数包。示例问题是使用递归计算参数包参数的数量。我在下面复制了他的解决方案。
template <typename... Args>
concept NonVoidArgs = sizeof...(Args) > 0;
template <typename... Args>
concept VoidArgs = sizeof...(Args) == 0;
template <VoidArgs...>
constexpr int NumArguments() {
return 0;
}
template<typename FirstArg, NonVoidArgs... RemainingArgs>
constexpr int NumArguments() {
return 1 + NumArguments<RemainingArgs...>();
}
例子:
int main() {
std::cout << NumArguments<int>() << std::endl; // 1
std::cout << NumArguments() << std::endl; // 0
std::cout << NumArguments<float, int, double, char>() << std::endl; // 4
return 0;
}
我认为这是一个比使用类模板专门化功能模板更好的解决方案。但是,我不确定它为什么会起作用。模板函数
template<typename FirstArg, NonVoidArgs... RemainingArgs>
constexpr int NumArguments()
似乎至少需要两个模板参数。需要有一个FirstArg,然后至少有1 个RemainingArgs。当只有一个模板参数时,为什么编译器会调用这个重载(?)?这种行为是否会对该解决方案产生任何问题?
【问题讨论】:
-
我看不出那些
concepts和NumArguments函数与仅仅做有什么不同:template<typename... Args> constexpr int NumArgs() { return sizeof...(Args); } -
@Brandon
NumArgs只是一个例子。在我的程序中,我发现我想使用参数包进行递归。由于一些关于专门模板函数的规则(我认为?),我在编写基本案例时遇到了麻烦。VoidArgs概念允许我用概念重载函数而不是专门化(我认为?)。NumArgs只是一个例子,这个问题是关于意外行为的。 -
@Brandon 但是是的,
NumArgs应该完全按照你说的做。
标签: c++ recursion variadic-templates c++20 c++-concepts