模板元程序查找相似的连续类型名称
Template metaprogram to find similar consecutive typenames
我是模板元编程的新手,曾试图创建一个程序,以查找参数包是否具有连续的相同类型名称。例如,<int, int>
、<int, char, char>
将返回true,而<int,char>
和<int, char, int>
将不返回true。
我设法编写了这段代码,但它似乎在将参数包的每个值与其本身进行比较。我只是在寻找一种方法来迭代参数包的值,并与它的连续元素进行比较。
template<typename T, typename U>
struct sameTypename{
enum {value = false};
};
template<typename T>
struct sameTypename<T, T>{
enum {value = true};
};
template <typename T, typename ...args>
struct consTypename{
enum {value = (sameTypename<consTypename<args...>, consTypename<args...>>::value)};
};
template <typename T>
struct consTypename<T, T>{
enum {value = true};
};
template <typename T>
struct consTypename<T>{
enum {value = false};
};
开始:
#include <type_traits>
template <typename ...P> struct has_adjacent_same_types : std::false_type {};
template <typename A, typename B, typename ...P> struct has_adjacent_same_types<A, B, P...>
: std::bool_constant<std::is_same_v<A,B> || has_adjacent_same_types<B, P...>::value> {};
我分别使用了: std::false_type {};
和: std::bool_constant<X> {};
而不是{enum{value = false};};
和{enum{value = X};};
,但这只是偏好问题。
我使用的一些功能来自C++17。如果你使用的是旧版本,请注意:
std::bool_constant
和std::is_same_v
仅从C++17开始可用(但之前可以使用std::integral_constant
和std::is_same<>::value
(。(c( @最大66
HolyBlackCat解决方案的变体。
template <typename ...>
struct has_adjacent_same_types : public std::false_type
{ };
template <typename T0, typename ... Ts>
struct has_adjacent_same_types<T0, T0, Ts...> : public std::true_type
{ };
template <typename T0, typename T1, typename ... Ts>
struct has_adjacent_same_types<T0, T1, Ts...>
: public has_adjacent_same_types<T1, Ts...>
{ };
两个更简单的专业而不是一个,更复杂。
本质上是一样的(我想(,但我觉得读起来和理解起来有点清楚。
我还提出了一个完全不同的解决方案,它使用模板折叠(不幸的是,只有C++17或更新版本(而不是模板递归。
template <typename...>
struct sae_helper;
template <typename ... Ts, typename ... Us>
struct sae_helper<std::tuple<Ts...>, std::tuple<Us...>>
: public std::bool_constant<(std::is_same_v<Ts, Us> || ...)>
{ };
template <typename ... Ts>
struct some_adjacent_equal
: public sae_helper<std::tuple<void, Ts...>, std::tuple<Ts..., void>>
{ };
如果void
是要检查的类型列表中的一个可能类型,那么从some_adjacent_equal
而不是void
调用sae_helper
显然必须使用不同的类型。
我认为,当类型列表很长时,这种解决方案比递归解决方案更可取,因为要避免编译器模板的递归限制。
如果您可以使用C++14,您可以使用constexpr
函数而不是模板折叠(以及标签类型而不是void(,如下所示
template <typename ... Ts, typename ... Us>
constexpr bool sae_helper (std::tuple<Ts...> const &,
std::tuple<Us...> const &)
{
using unused = bool[];
bool ret { false };
(void)unused { true, ret |= std::is_same<Ts, Us>::value... };
return ret;
}
struct no_type
{ };
template <typename ... Ts>
struct some_adjacent_equal
: public std::integral_constant<bool, sae_helper(std::tuple<no_type, Ts...>{},
std::tuple<Ts..., no_type>{})>
{ };
但是,通过这种方式,您可以在评估中忽略短路。
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 模板元程序查找相似的连续类型名称
- 可以将两个相同类型的连续数组视为一个数组吗?
- 如何将 n 个连续元素插入到元素类型不可复制的 std::vector 中?
- 如何创建非 POD 类型的连续内存池?
- POD 结构(相同类型的成员):成员是否位于连续的内存位置?
- 在编译时检查特征类型保存的数据在内存中是否连续
- 多态类型的连续存储
- Boost.SSpirit.x3避免将同一类型的两个连续属性塌陷为向量
- 递归类型真的是构建不连续的任意大小数据结构的唯一方法吗
- 在整数数据类型和连续两个字符类型之后.第 2 个字符的数据类型跳过..为什么
- 如何确保每100个给定类型的对象都被分配到连续内存中
- boost::asio-signal_set处理程序仅在捕获第一个信号后执行,并忽略相同类型的连续信号
- 为什么在visual studio中连续的int数据类型变量位于12个字节的偏移