是否有可能编写一个函数模板来返回参数的数量是否能被N整除?

Is it possible to write a function template which returns whether the number of arguments is divisible by N?

本文关键字:是否 参数 整除 返回 有可能 一个 函数模板      更新时间:2023-10-16

我一直在学习可变模板,在这篇优秀的博客文章的帮助下,我已经设法编写了一个函数模板even_number_of_args,它返回它接收的参数数量是否能被2整除。

#include <iostream>
bool even_number_of_args() {
    return true;
}
template <typename T>
bool even_number_of_args(T _) {
    return false;
}
template<typename T, typename U, typename... Vs>
bool even_number_of_args(T _, U __, Vs... vs) {
  return even_number_of_args(vs...);
}
int main() {
    std::cout << even_number_of_args()                   << std::endl; // true
    std::cout << even_number_of_args(1)                  << std::endl; // false
    std::cout << even_number_of_args(1, "two")           << std::endl; // true
    std::cout << even_number_of_args(1, "two", 3.0)      << std::endl; // false
    std::cout << even_number_of_args(1, "two", 3.0, '4') << std::endl; // true
}

我想知道是否有可能编写一个函数模板,作为模板参数,一个数字N,并返回它接收的参数数量是否为N的倍数。例如,函数可能看起来像这样:

number_of_args_divisible_by_N<1>(1, "two", 3.0, '4'); // true
number_of_args_divisible_by_N<2>(1, "two", 3.0, '4'); // true
number_of_args_divisible_by_N<3>(1, "two", 3.0, '4'); // false
number_of_args_divisible_by_N<4>(1, "two", 3.0, '4'); // true

是的,就像

一样简单
template<int N, typename... Ts>
constexpr bool number_of_args_divisible_by(Ts&&...)
{
    return sizeof...(Ts) % N == 0;
}

或者,您可以返回一个对元编程更友好的类型:

template<int N, typename... Ts>
constexpr integral_constant<bool, sizeof...(Ts) % N == 0>
number_of_args_divisible_by(Ts&&...)
{
    return {};
}

虽然krzaq的解决方案非常好,但我认为实现sizeof...背后的"魔法"可以作为一个有趣的学习练习。

它使用了一种模板元编程中非常常见的技术——一个覆盖基本情况的非模板函数和一个通过一步减少问题的模板函数:

// Base case
int count_args() {
    return 0;
}
// Reduction
template<typename T, typename... Vs>
int count_args(T _, Vs... vs) {
    return 1 + count_args(vs...);
}

有了这个功能,您可以使用krzaq的答案中的方法实现可除性检查器:

template<int N,typename... Vs>
bool is_arg_divisible(Vs... vs) {
    return count_args(vs...) % N == 0;
}

演示。

相关文章: