如何将任何化合物还原为非化合物类型
How to reduce any compound to non-compound type
要求:给定复合类型"T",使用什么非复合类型作为基本类型?
到目前为止,我的尝试是这个模板别名:
template <class T>
using reduce_to_non_compound_t =
std::remove_all_extents_t<
std::remove_pointer_t<
std::remove_cvref_t < T >
> >;
例如
// array of pointers to string
using arr_of_sp = std::string * (&)[42];
// should pass
static_assert( std::is_same_v<
std::string,
reduce_to_non_compound_t<arr_of_sp>
> )
测试这一点的许多用例可能非常大。在我进一步讨论这个问题之前,我想问一下是否有人有更好的想法甚至实施?
我在问这样的事情是否合乎逻辑。这就是用例的用武之地。如果它是合乎逻辑的,那么它可以被写出来。
如果,正如你所说,你只是想从类型中删除 cv 限定符、指针、引用和范围,那么你可以使用这个:
template <typename T, typename = void> struct base {using type = std::remove_cv_t<T>;};
template <typename T> using base_t = typename base<T>::type;
template <typename T> struct base<T, std::enable_if_t<std::is_array_v<T>>>
{using type = base_t<std::remove_all_extents_t<T>>;};
template <typename T> struct base<T, std::enable_if_t<std::is_reference_v<T>>>
{using type = base_t<std::remove_reference_t<T>>;};
template <typename T> struct base<T, std::enable_if_t<std::is_pointer_v<T>>>
{using type = base_t<std::remove_pointer_t<T>>;};
用法:
static_assert(std::is_same_v<int, base_t<const int *volatile[4]>>);
它可以轻松扩展以使用成员函数指针、函数或其他内容。
我可能会谦虚地报告,我建议的(在问题中(解决方案确实有效。
特别感谢圣黑猫先生,他发现了一个缺陷,所以我添加了"dbj::remove_all_ptr_t"。现在解决方案现在也适用于双指针、三指针等。
魔杖盒在这里
namespace dbj
{
template <typename T> struct remove_all_ptr { typedef T type; };
template <typename T> struct remove_all_ptr<T*> {
using type = typename remove_all_ptr<std::remove_cv_t<T>>::type;
};
template <typename T>
using remove_all_ptr_t = typename remove_all_ptr<T>::type ;
template< class T >
struct remove_cvref {
typedef std::remove_cv_t<std::remove_reference_t<T>> type;
};
template< class T >
using remove_cvref_t = typename remove_cvref<T>::type;
template <class T>
using to_base_t =
remove_all_ptr_t< std::remove_all_extents_t< remove_cvref_t < T > > >;
} // dbj
圣黑猫先生解决方案也有效。虽然有些人可能会觉得它有点复杂(我个人认为不是(。
我的解决方案在命名空间dbj
中,他的解决方案在命名空间hbc
中。 这是我的快速测试。
// testing
static_assert(std::is_same_v<std::string, hbc::base_t<std::string * (&)[42]>>);
static_assert(std::is_same_v<std::string ,dbj::to_base_t<std::string * (&)[42]>>);
static_assert(std::is_same_v<void (), hbc::base_t<void ()>>);
static_assert(std::is_same_v<void (), dbj::to_base_t<void ()>>);
//
struct X { char data{}; char method () const { return {};} };
static_assert(std::is_same_v<X, hbc::base_t<X (&) []>>);
static_assert(std::is_same_v<X, dbj::to_base_t<X (&) []>>);
//
using method_t = char (X::*)() ;
static_assert(std::is_same_v<method_t, hbc::base_t< method_t (&) []>>);
static_assert(std::is_same_v<method_t, dbj::to_base_t< method_t (&) []>>);
两种解决方案都通过了上述测试。魔杖盒在这里。 谢谢大家的宝贵讨论。
相关文章:
- ArduinoJson 6.15.2:JsonObject没有命名类型
- 防止主数据类型C++的隐式转换
- 大量序列中核苷酸类型的快速计数
- 如何从C++中的依赖类型中获得它所依赖的类型
- 有关插入适配器的错误。[错误]请求从 'back_insert_iterator<vector<>>' 类型转换为非标量类型
- 是否可以初始化不可复制类型的成员变量(或基类)
- 如何获取std::result_of函数的返回类型
- 从父命名空间重载类型
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- Openssl 1.1.1d无效使用不完整的类型"struct dsa_st"
- 访问者访问变体并返回不同类型时出错
- 在VS2010-VS2015下编译时,如何使用decltype作为较大类型表达式的LHS
- 处理小于cpu数据总线的数据类型.(c++转换为机器代码)
- C++ 雷神库 - 使用资源加载器类时出现问题(不命名类型)
- 模板元程序查找相似的连续类型名称
- 是否可以从int转换为enum类类型
- 构造函数正在调用一个使用当前类类型的函数
- 如何将任何化合物还原为非化合物类型
- 化合物类型,常量和自动C++