【问题标题】:Implementing an `is_similar` type trait based on the definition of the C++ standard根据 C++ 标准的定义实现 `is_similar` 类型特征
【发布时间】:2020-07-03 21:34:05
【问题描述】:

我正在尝试根据标准给出的定义实现is_similar 类型特征(详情here):

T1T2 两种类型如果有 cv-decompositions 是相似的 具有相同的n 使得对应的Pi 组件是 相同或一个是“Ni 数组”,另一个是“未知数组” bound of",U表示的类型是一样的。

但是,我不确定是否完全理解它的含义,以及如何实现它:

template <class T, class U, class = void>
struct is_similar_base: std::false_type {};

template <class T, class U>
struct is_similar_base<T, U, /* ??? */ >: std::true_type {};

template <class T, class U>
struct is_similar: is_similar_base<T, U> {};

template <class T, class U>
inline constexpr bool is_similar_v = is_similar<T, U>::value;

欢迎任何帮助。

【问题讨论】:

    标签: c++ language-lawyer typetraits


    【解决方案1】:

    cv-decomposition 将一个类型“剥离”为const/volatile 限定符和指针/数组间接层的交替层。如果指针/数组间接寻址相同(允许“未知边界数组”匹配“n”数组)并且下面的类型相同(忽略 cv 限定符),则类型相似。

    所以,

    // every type is similar to itself
    template<typename T, typename U>
    struct is_similar_impl : std::is_same<T, U> { };
    // we don't care about cv-qualifiers
    template<typename T, typename U>
    struct is_similar : is_similar_impl<std::remove_cv_t<T>, std::remove_cv_t<U>> { };
    // peeling off different kinds of pointers/arrays
    template<typename T, typename U>
    struct is_similar_impl<T*, U*> : is_similar<T, U> { };
    template<typename C, typename T, typename U>
    struct is_similar_impl<T C::*, U C::*> : is_similar<T, U> { };
    template<std::size_t N, typename T, typename U>
    struct is_similar_impl<T[N], U[N]> : is_similar<T, U> { };
    template<std::size_t N, typename T, typename U>
    struct is_similar_impl<T[N], U[]> : is_similar<T, U> { };
    template<std::size_t N, typename T, typename U>
    struct is_similar_impl<T[], U[N]> : is_similar<T, U> { };
    
    template<typename T, typename U>
    constexpr inline bool is_similar_v = is_similar<T, U>::value;
    

    Godbolt and test cases

    【讨论】:

    • @Vincent 是的。我设法不为此做一个测试用例,但倒数第二个测试用例检查 const volatile 指向成员的指针是否类似于不合格的指向成员的指针。例如。 is_similar_v&lt;int *const, int*&gt;true
    • 做得很好。一个建议:在目前的形式下,只要它可以找到两种类型的并行分解,它将继续递归,即使其余序列相同。我想一个快速而稍微有点脏的优化是添加template&lt;class T&gt; struct is_similar&lt;T, T&gt; : std::true_type { };,以便它在遇到相同类型时更早停止(或稍微改变结构以便它真正尽快停止)。
    猜你喜欢
    • 1970-01-01
    • 2019-12-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-01
    相关资源
    最近更新 更多