boost::hana tag_of 实现

Per*_*-lk 4 c++ boost partial-specialization c++14

我想知道在when没有案例基础的boost::hana::when<false>情况下,专业化是如何工作的。

boost::hana::tag_of 执行:

 template<bool condition>
 struct when; // forward declaration only

 template<typename T, typename = void>
 struct tag_of;

 template<typename T, typename>
 struct tag_of : tag_of<T, when<true> >
 {};

 template<typename T, bool condition>
 struct tag_of<T, when<condition> >
 {
    using type = T;
 };
Run Code Online (Sandbox Code Playgroud)

和一个测试示例:

 struct my_tag {};
 struct my_tag2 {};

 namespace boost {
    namespace hana {

       template<class T>
       struct tag_of<T, when<std::is_same<T, int>{}()> >
       {
           using type = my_tag;
       };

       template<class T>
       struct tag_of<T, when<std::is_same<T, unsigned>{}()> >
       {
          using type = my_tag2;
       };
    }
}

int main()
{
   using type = boost::hana::tag_of<int>::type;
   std::cout << std::is_same<type, my_tag>{} << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

我想知道为什么std::is_same<T, int>{}()(或与::valuewhich 相同)是比 更专业的部分专业化std::is_same<T, unsigned>{}(),以及为什么如果两种情况的条件都为假,when<condition>则更专业化。

我已经完成了很多元函数,并使用了专业化、参数包和排序,但在这种情况下,我没有看到一些东西。

问题是,如果这种情况没有默认实现,我不明白为什么模板的trueorfalsewhen会很重要false

Bar*_*rry 5

我想知道为什么std::is_same<T, int>{}()(或与::valuewhich 相同)是比 更专业的部分专业化std::is_same<T, unsigned>{}(),以及为什么,如果这两种情况的条件都为假,when<condition>则更专业化。

不是更专业。它们从来都不是可行的专业。让我们来看看当我们尝试实例化hana::tag_of<int>.

  1. 填写默认模板参数。在这种情况下,第二个模板参数默认为void,所以我们真的有hana::tag_of<int, void>.
  2. 考虑哪些部分专业化是可行的。在这种情况下,没有一个人是活的-我们的类型(int)不是一个引用或CV-合格的,它不是任何一种when<condition>。由于没有一个专业化是可行的,我们实例化主模板。
  3. 主要tag_of<T, void>继承自tag_of<T, when<true>>. 所以现在我们需要实例化第二种类型,这意味着我们重做第 2 步。
  4. 现在,两种不同的专业是可行的:

    // from hana's core
    template <typename T, bool condition> 
    struct tag_of<T, when<condition>>
    
    // yours
    template <typename T>
    struct tag_of<T, when<std::is_same<T, int>{}()>>
    
    Run Code Online (Sandbox Code Playgroud)

    请注意,您的其他专业化不可行- 因为std::is_same<T, unsigned>{}false,我们正在尝试匹配when<true>.

  5. 在这两个专业化之间,如果我们通过偏序规则,您的专业化会更加专业化 - 所以它被选中并实例化。

因此,hana::tag_of<int>::typeis hana::tag_of<int, void>::typeis hana::tag_of<int, when<true>>::typeis hana::tag_of<int, when<std::is_same<T, int>{}()>>::typeis my_tag


问题是,如果这种情况没有默认实现,我不明白为什么when 模板的trueorfalse值会很重要false

以上内容希望说明为什么它很重要。我们没有when<false>直接实例化,但是您可以编写一个替代when<false>(如您的when<std::is_same<T, unsigned>{}()>专业化)的专业化。

以及为什么,如果条件适用false于两种情况,when<condition>则更专业。

由于我们正在实例化when<true>,那些条件为 的特化false被简单地从候选集中排除。可行的专业化列表只是减少到 hana 直接提供的列表。它不是“更专业”——它完全可行。


同样值得注意的是,它tag_of为您提供了多种专业化方法。您可以提供一些布尔条件使用void_t. 或者,您可以只专注于顶级:

template <>
struct tag_of<int, void> {
    using type = my_tag;
};
Run Code Online (Sandbox Code Playgroud)

这将在上面的第 2 步短路,跳过所有其他实例。