c++ - 递归模板参数包编程
问题描述
我对 C++ 模板编程很陌生。我想设计一个功能element
,例如
element<3, 3, 3, 3, 3>
将返回 3element<3, 3, 2>
将使断言失败#include <iostream> #include <cstdlib> namespace meta { template<typename T> constexpr T element(T x) { return x; } template<typename T, typename... Ts> constexpr T element(T x, Ts... xs) { constexpr T oth = element(xs...); // $C$ static_assert(oth == x, "element Mismatch"); return x; } template<int... DIMS> void get_elements() { std::cout << "elements " << element(DIMS...); // $A$ } } int main(int argc, char ** argv) { meta::get_elements<2, 3, 4>(); // $B$ static constexpr int D1 = 3, D2 = 3; meta::get_elements<D1, D2>(); }
但是 GCC withstd=c++14
失败了
在 'constexpr T meta::element(T, Ts ...) [with T = int; Ts = {int,int}]':
$A$: 需要从 'void meta::get_elements() [with int ...DIMS = {2, 3, 4}]'</p>
$B$:从这里需要
$C$: 错误: 'xs#0' 不是常量表达式
$C$: 错误: 'xs#1' 不是常量表达式
我想利用递归对列表中的每个模板参数执行相等检查,如果它们都相等则返回其中一个。
解决方案
这是 C++17 中的一个简单解决方案:
template <int Head, int... Tail> struct element
{
static_assert((... && (Head == Tail)), "missmatch elements");
static constexpr auto value = Head;
};
template <int... I> constexpr auto element_v = element<I...>::value;
auto test()
{
// element_v<3, 3, 1>; // assert fail
constexpr int A = 3, B = 3;
return element_v<3, 3, A, B>;
}
在godbolt上看到它
推荐阅读
- c++ - const char 指针模板特化
- python - 如何从字典中提取提取特定键?
- angular - Ionic 中的条纹结帐
- recoiljs - 如何使用反冲实现典型用例
- xamarin - 删除 Xamarin Forms UWP 的自定义渲染器 SearchBar 上的边框
- android - 如何在 Android 上的重点文本视图上显示计算器的结果
- java - 如何在 Java Graphics 中撤消paintComponent 中的绘图
- jquery - 带有附加 div 的 jQuery 手风琴要切换
- c# - ImageResizer - 指定纵向或横向
- python - 找不到 gdal 配置