c++ - 处理通用代码中不一致的 typedef

标签 c++ templates metaprogramming typedef template-meta-programming

我经常在大型代码库中遇到不遵循 typedef 标准约定的代码,例如ThisType而不是this_type .

编写我不再依赖的通用代码 this_type意味着我必须为没有 this_type 的每种类型提供一些脚手架代码.

我想都是this_typeThisType可以定义。然而,在大型代码库中,这会增加额外的噪音,并且是审查需要定期检查的内容。

有没有办法将其包装在 type_trait 中这样我就可以写一些类似的东西:this_type<SomeType>::value_type 其他一些通用解决方案?

最佳答案

也许可以用更简单的方式来完成......无论如何,我建议使用标签调度/SFINAE 解决方案。

首先,一个简单的递归tag结构

template <std::size_t N>
struct tag : public tag<N-1u>
{ };

template <>
struct tag<0u>
{ };

避免在定义了多种可能类型名称的情况下出现歧义。

然后为您想要从可能的类型中提取的每种类型提供一个模板函数(仅声明);一个用于类型

template <typename T, std::void_t<typename T::type>* = nullptr>
typename T::type getType (tag<0u>);

一个用于this_type

template <typename T, std::void_t<typename T::this_type>* = nullptr>
typename T::this_type getType (tag<1u>);

一个用于ThisType

template <typename T, std::void_t<typename T::ThisType>* = nullptr>
typename T::ThisType getType (tag<2u>);

还有一个(有点傻)MySillyTypeName

template <typename T, std::void_t<typename T::MySillyTypeName>* = nullptr>
typename T::MySillyTypeName getType (tag<3u>);

请注意标签的数量是不同的:这可以避免可能的歧义并为名称提供优先顺序。

现在是一个简单的结构,使用 getType() 来提取所需的类型

template <typename T, typename U = decltype(getType<T>(tag<100u>()))>
struct GetType { using type = U; };

以下是完整的编译C++17示例

#include <type_traits>

template <std::size_t N>
struct tag : public tag<N-1u>
{ };

template <>
struct tag<0u>
{ };

template <typename T, std::void_t<typename T::type>* = nullptr>
typename T::type getType (tag<0u>);

template <typename T, std::void_t<typename T::this_type>* = nullptr>
typename T::this_type getType (tag<1u>);

template <typename T, std::void_t<typename T::ThisType>* = nullptr>
typename T::ThisType getType (tag<2u>);

template <typename T, std::void_t<typename T::MySillyTypeName>* = nullptr>
typename T::MySillyTypeName getType (tag<3u>);

template <typename T, typename U = decltype(getType<T>(tag<100u>()))>
struct GetType { using type = U; };

struct foo1 { using type = short; };
struct foo2 { using this_type = int; };
struct foo3 { using ThisType = long; };
struct foo4 { using MySillyTypeName = long long; };

int main()
{
  static_assert( std::is_same_v<short,     GetType<foo1>::type> );
  static_assert( std::is_same_v<int,       GetType<foo2>::type> );
  static_assert( std::is_same_v<long,      GetType<foo3>::type> );
  static_assert( std::is_same_v<long long, GetType<foo4>::type> );
}

关于c++ - 处理通用代码中不一致的 typedef,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71340563/

相关文章:

c++ - clang 或 gcc 是否利用引用限制进行别名分析

基于 C++ 策略的设计 : Inheritance vs composition

javascript - 需要下划线模板帮助 - 模板化集合

ruby - 类中的产量 << 类方法中的 self

python - 如何获得对在 python 中实现描述符对象的所有类的引用

c++ - 需要澄清 'reverse (data, data+n)' 在这段代码中做了什么

c++ - 对具有指针的结构 vector 进行排序

c++ - "explicit template argument list not allowed"使用 g++,但使用 clang++ 编译?

macros - 从 Julia 生成的函数中调用宏

c++ - 所有按钮都应该包含对 MVC 代码 (C++) 中的 Controller 的引用吗?