template-meta-programming 相关问题

模板元编程是一种元编程技术,其中编译器使用模板生成临时源代码,该代码由编译器与其余源代码合并然后编译。

通过SFINAE进行函数模板检测

我想编写一个函数,将 lambda 分派到外部库函数模板(如果库中存在此函数模板)或直接执行 lambda。 我们可以...

回答 0 投票 0

是否可以将花括号初始化列表作为模板参数传递?

我有这门课 模板 结构体ArrayPrimitive { constexpr ArrayPrimitive(const ValueType (&array)[Size]) { std::copy(数组,数组+大小,d...

回答 1 投票 0

C++ 将匿名数组作为模板参数传递

我有这门课 模板 结构体ArrayPrimitive { constexpr ArrayPrimitive(const ValueType (&array)[Size]) { std::copy(数组,数组+大小,d...

回答 1 投票 0

C++ 中嵌套结构的模板

我想编写这段代码,但它会产生错误。 模板 结构体A { 结构体 B { }; B f() { 返回 B{}; } }; 模板 constexpr bool val = fals...

回答 2 投票 0

Sfinae 模板化隐式转换运算符重载

我正在尝试模板化一些转换运算符函数来接受各种算术类型,即有符号/无符号整数/浮点类型,因此有4种不同的函数模板

回答 1 投票 0

双折表达式替换分支语句

我试图弄清楚如何使用折叠表达式(或其他元编程技术)来摆脱下面代码片段中的“if else”分支。 模板 是...

回答 1 投票 0

从文件中加载类型数据(模板元编程(?))

我正在尝试创建一个模板类,它将从给定类型的文件中读取数据到 std::variant 向量中。 ...

回答 1 投票 0

如何将变量名作为字符串传递给函数? (Clojure 脚本)

情况描述 我想为某个元素制作一个表单模板,但它们必须动态创建。组件中涉及的元数据应该使用传递的变量名称...

回答 1 投票 0

如何让 C++ ADL 查看模板的所有实例?

我正在关注如何在 C++ 中实现常量表达式计数器教程,并尝试修复没有宏、标记或外部工具的 C++14 反射谈话限制。 基本...

回答 1 投票 0

从类型列表中删除类型 C++ 元编程

C++元编程中从类型列表中删除类型是什么意思。任何人都可以提出任何简单的例子吗? 类 null_typelist {}; 模板 结构

回答 1 投票 0

c++ 派生类的类型列表

使用 CRTP(奇怪的重复模板模式),您可以提供一个具有派生类知识的基类。创建一个存储每个类的实例的数组并不难...

回答 2 投票 0

C++ 中编译时拓扑排序超过递归深度

你好:) 我正在使用 C++ 模板元编程实现编译时拓扑排序算法。该算法旨在对游戏中不同系统之间的依赖关系图进行排序

回答 1 投票 0

如何声明一个具有 N 个 double 类型参数的函数?

我想要一个能够存储接受“N”个双参数的函数对象的模板类。该伪代码使用不存在的 std::repeated_type 模板函数...

回答 1 投票 0

检测函数类型是否为 noexcept

我想知道是否有技巧可以简化 trait 的编写以返回类型是否为 noexcept 函数。目前我的实现如下,它只列出了所有...

回答 2 投票 0

由于非类型参数特化导致模板实例化不明确

我正在尝试使用 TMP 实现列表及其操作。 以下代码无法编译,Insert_t 无法实例化(最后一行): #包括 模板 我正在尝试使用 TMP 实现列表及其操作。 以下代码编译不通过,Insert_t实例化失败(最后一行): #include <type_traits> template <int... I> struct List; template <int Em, typename TList> struct Append; template <int Em, typename TList> using Append_t = typename Append<Em, TList>::type; template <int Em, int... I> struct Append<Em, List<I...>> { using type = List<Em, I...>; }; template <int Em, int Idx, typename TList> struct Insert; template <int Em, int Idx, typename TList> using Insert_t = typename Insert<Em, Idx, TList>::type; template <int Em, int... I> struct Insert<Em, 0, List<I...>> : Append<Em, List<I...>> {}; template <int Em, int Idx, int H, int... I> struct Insert<Em, Idx, List<H, I...>> : Append<H, Insert_t<Em, Idx-1, List<I...>>> {}; static_assert(std::is_same_v<Insert_t<4, 4, List<0, 1, 2, 3>>, List<0, 1, 2, 3, 4>>); // OK static_assert(std::is_same_v<Insert_t<-1, 3, List<6, 3, 1, 4>>, List<6, 3, 1, -1, 4>>); // Fails g++ 编译器给出以下错误,clang 提供相同的错误。我不明白为什么实例化不明确,因为我提供了索引为 0 的专业化: main.cpp: In instantiation of ‘struct Insert<-1, 1, List<1, 4> >’: main.cpp:27:8: recursively required from ‘struct Insert<-1, 2, List<3, 1, 4> >’ main.cpp:27:8: required from ‘struct Insert<-1, 3, List<6, 3, 1, 4> >’ main.cpp:21:7: required by substitution of ‘template<int Em, int Idx, class TList> using Insert_t = typename Insert::type [with int Em = -1; int Idx = 3; TList = List<6, 3, 1, 4>]’ main.cpp:30:61: required from here main.cpp:27:8: error: ambiguous template instantiation for ‘struct Insert<-1, 0, List<4> >’ 27 | struct Insert<Em, Idx, List<H, I...>> : Append<H, Insert_t<Em, Idx-1, List<I...>>> {}; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:24:8: note: candidates are: ‘template<int Em, int ...I> struct Insert<Em, 0, List<I ...> > [with int Em = -1; int ...I = {4}]’ 24 | struct Insert<Em, 0, List<I...>> : Append<Em, List<I...>> {}; | ^~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:27:8: note: ‘template<int Em, int Idx, int H, int ...I> struct Insert<Em, Idx, List<H, I ...> > [with int Em = -1; int Idx = 0; int H = 4; int ...I = {}]’ 27 | struct Insert<Em, Idx, List<H, I...>> : Append<H, Insert_t<Em, Idx-1, List<I...>>> {}; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp:27:8: error: invalid use of incomplete type ‘struct Insert<-1, 0, List<4> >’ main.cpp:18:8: note: declaration of ‘struct Insert<-1, 0, List<4> >’ 18 | struct Insert; | ^~~~~~ main.cpp: In instantiation of ‘struct Insert<-1, 2, List<3, 1, 4> >’: main.cpp:27:8: required from ‘struct Insert<-1, 3, List<6, 3, 1, 4> >’ main.cpp:21:7: required by substitution of ‘template<int Em, int Idx, class TList> using Insert_t = typename Insert::type [with int Em = -1; int Idx = 3; TList = List<6, 3, 1, 4>]’ main.cpp:30:61: required from here main.cpp:27:8: error: no type named ‘type’ in ‘struct Insert<-1, 1, List<1, 4> >’ 27 | struct Insert<Em, Idx, List<H, I...>> : Append<H, Insert_t<Em, Idx-1, List<I...>>> {}; | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ main.cpp: In instantiation of ‘struct Insert<-1, 3, List<6, 3, 1, 4> >’: main.cpp:21:7: required by substitution of ‘template<int Em, int Idx, class TList> using Insert_t = typename Insert::type [with int Em = -1; int Idx = 3; TList = List<6, 3, 1, 4>]’ main.cpp:30:61: required from here main.cpp:27:8: error: no type named ‘type’ in ‘struct Insert<-1, 2, List<3, 1, 4> >’ main.cpp: In substitution of ‘template<int Em, int Idx, class TList> using Insert_t = typename Insert::type [with int Em = -1; int Idx = 3; TList = List<6, 3, 1, 4>]’: main.cpp:30:61: required from here main.cpp:21:7: error: no type named ‘type’ in ‘struct Insert<-1, 3, List<6, 3, 1, 4> >’ 21 | using Insert_t = typename Insert<Em, Idx, TList>::type; | ^~~~~~~~ main.cpp:30:20: error: template argument 1 is invalid 30 | static_assert(std::is_same_v<Insert_t<-1, 3, List<6, 3, 1, 4>>, List<6, 3, 1, -1, 4>>); | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 我想实现一个 Insert 操作以在列表 TList 中的位置 Idx 插入一个新元素 Em。在我的实现中,我为 Insert<Em, 0, List<I...>> 提供了一个模板部分特化,以便结构中提供的类型与 Append<Em, TList> 相同。但是,它被认为与其他偏特化 Insert<Em, Idx, List<H, I...>> 不明确。我不明白为什么,因为第一个部分专业化应该是模式限制的,以及如何解决这个问题。

回答 0 投票 0

将 constexpr 数组扩展为位置函数参数

习惯用x宏来生成强大的代码。我特别喜欢的功能之一是我不能弄乱值的顺序,也不能忘记一个。 我想知道有没有

回答 2 投票 0

C++ 模板特化如何使用默认布尔值?

我正在查看 libc++ 的代码,我注意到了这个片段: // __指针 _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_pointer, 指针); 模板 我正在查看 libc++ 的代码,我注意到了这个片段: // __pointer _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(__has_pointer, pointer); template <class _Tp, class _Alloc, class _RawAlloc = __libcpp_remove_reference_t<_Alloc>, bool = __has_pointer<_RawAlloc>::value> struct __pointer { using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer; }; template <class _Tp, class _Alloc, class _RawAlloc> struct __pointer<_Tp, _Alloc, _RawAlloc, false> { using type _LIBCPP_NODEBUG = _Tp*; }; 让我疑惑的是这一行: bool = __has_pointer<_RawAlloc>::value 这段代码的语义非常清楚:这里我们调用一个元函数__has_pointer,如果它为真,我们就使用__pointer的第一个实现,如果不是,我们就使用第二个(显式为假的那个)在其模板参数中)。我很困惑,因为我不明白这是如何工作的,第一个实例不应该在其模板参数中有一个明确的true然后模板专业化开始吗?如果是这样,那么我们需要在启动此模板时调用元函数,所以也许bool = __has_pointer<_RawAlloc>::value>是它的简写?我想知道这里使用了什么样的机制才能允许这样做。用于使这项工作的规则是什么? _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX的完整实现可以在这里找到: #define _LIBCPP_ALLOCATOR_TRAITS_HAS_XXX(NAME, PROPERTY) \ template <class _Tp, class = void> struct NAME : false_type { }; \ template <class _Tp> struct NAME<_Tp, __void_t<typename _Tp:: PROPERTY > > : true_type { } 第一个实例不应该在其模板参数中有一个明确的 true 然后模板专业化开始吗? 首先,您定义一个模板。如果您尝试实例化一个模板,就会得到这个“基本”模板。 然后你可以定义一个专业化。如果模板参数与专业化匹配,那么您将获得专业化模板。惊喜! template <class _Tp, class _Alloc, class _RawAlloc = __libcpp_remove_reference_t<_Alloc>, bool = __has_pointer<_RawAlloc>::value> struct __pointer 让我们忽略专业化。如果没有专门化,这是您在实例化此模板时将获得的模板。这就是当最后一个模板参数是 true 或 false 时得到的结果。没关系。这是你的模板。好好享受。祝你胃口好 但是等等,你忘了:你也有专长。别急:如果最后一个模板参数是false,你的餐点就是专业化。 但是,如果最后一个模板参数原来是true没有任何变化,你仍然得到原始模板。其他地方都不需要设置为“显式真实”。 话虽如此,是的,您实际上可以通过 two 专业化,甚至不定义基本模板,使事情看起来像这样: template <class _Tp, class _Alloc, class _RawAlloc = __libcpp_remove_reference_t<_Alloc>, bool = __has_pointer<_RawAlloc>::value> struct __pointer; template <class _Tp, class _Alloc, class _RawAlloc> struct __pointer<_Tp, _Alloc, _RawAlloc, true> { using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer; }; template <class _Tp, class _Alloc, class _RawAlloc> struct __pointer<_Tp, _Alloc, _RawAlloc, false> { using type _LIBCPP_NODEBUG = _Tp*; }; 这在逻辑上是等价的。这两种选择在逻辑上是等价的。 这只是一个类型特征,用于使用类的部分专业化 分派到特定的实现。有 template <class _Tp, class _Alloc, class _RawAlloc = __libcpp_remove_reference_t<_Alloc>, bool = __has_pointer<_RawAlloc>::value> struct __pointer { using type _LIBCPP_NODEBUG = typename _RawAlloc::pointer; }; 定义了一个初级类模板,模板的bool = __has_pointer<_RawAlloc>::value部分是一个bool非类型tmplate参数,默认为__has_pointer<_RawAlloc>::value的值。 __has_pointer<_RawAlloc>::value 将返回 true 如果 _RawAlloc 有一个 pointer 成员和 false 否则。 接下来我们有 template <class _Tp, class _Alloc, class _RawAlloc> struct __pointer<_Tp, _Alloc, _RawAlloc, false> { using type _LIBCPP_NODEBUG = _Tp*; }; 这是主模板的偏特化,只要最后一个模板参数是false.就会被使用 这意味着当 _RawAlloc 有 pointer 成员时使用主模板,而当它没有时使用专业化

回答 2 投票 0

为 integral_constant 添加特化的程序的行为是未定义的

我不熟悉在 C++ 中使用模板元编程。 我希望能够将整数和类型名的混合传递给可变参数模板。我无法同时指定两者,所以我使用 typename...pack...

回答 0 投票 0

为 integral_constant 添加特化的程序的 C++ 行为是未定义的

我不熟悉在 C++ 中使用模板元编程。 我希望能够将整数和类型名的混合传递给可变参数模板。我无法同时指定两者,所以我使用 typename...pack....

回答 0 投票 0

派生类模板化时访问基础成员数据错误

我对奇怪的重复模板有以下问题,当我尝试访问 CRTP 基类的数据成员时出现问题。 模板 结构基础{ 内部保护...

回答 1 投票 0

© www.soinside.com 2019 - 2024. All rights reserved.