是否可以编写一个 returns 参数个数是否能被 N 整除的函数模板?
Is it possible to write a function template which returns whether the number of arguments is divisible by N?
我一直在学习可变参数模板,并且在 this excellent blog post 的帮助下,我设法编写了一个函数模板 even_number_of_args
,其中 returns 参数的数量它接收到的值可以被 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
和 returns 它接收的参数数量是否是 [ 的倍数=14=]。例如,该函数可能如下所示:
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;
}
或者,您可以 return 元编程更友好的类型:
template<int N, typename... Ts>
constexpr integral_constant<bool, sizeof...(Ts) % N == 0>
number_of_args_divisible_by(Ts&&...)
{
return {};
}
虽然krzaq的解决方案很好,但我认为实现sizeof...
后面的"magic"可以作为一个有趣的学习练习。
它使用了一种在模板元编程中非常常见的技术——一个覆盖基本情况的非模板函数,以及一个将问题减少一步的模板函数:
// 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;
}
我一直在学习可变参数模板,并且在 this excellent blog post 的帮助下,我设法编写了一个函数模板 even_number_of_args
,其中 returns 参数的数量它接收到的值可以被 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
和 returns 它接收的参数数量是否是 [ 的倍数=14=]。例如,该函数可能如下所示:
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;
}
或者,您可以 return 元编程更友好的类型:
template<int N, typename... Ts>
constexpr integral_constant<bool, sizeof...(Ts) % N == 0>
number_of_args_divisible_by(Ts&&...)
{
return {};
}
虽然krzaq的解决方案很好,但我认为实现sizeof...
后面的"magic"可以作为一个有趣的学习练习。
它使用了一种在模板元编程中非常常见的技术——一个覆盖基本情况的非模板函数,以及一个将问题减少一步的模板函数:
// 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;
}