【问题标题】:boost::hana tag_of implementationboost::hana tag_of 实现
【发布时间】:2017-05-24 22:31:11
【问题描述】:

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

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;
 };

还有一个测试例子:

 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;
}

我想知道为什么std::is_same&lt;T, int&gt;{}()(或与::value 相同)是比std::is_same&lt;T, unsigned&gt;{}() 更专业的偏特化,为什么如果两种情况的条件都为假,when&lt;condition&gt; 更专业的。

我已经完成了很多元函数,并使用了特化和参数包以及排序,但在这种情况下,有些东西我看不到。

如果false 案例没有默认实现,我不明白为什么when 模板的true 或false 值很重要。

【问题讨论】:

    标签: c++ boost c++14 partial-specialization


    【解决方案1】:

    我想知道为什么std::is_same&lt;T, int&gt;{}()(或与::value 相同)是比std::is_same&lt;T, unsigned&gt;{}() 更专业的偏特化,为什么如果两种情况的条件都为假,when&lt;condition&gt; 更专业的。

    它不更专业。他们根本就不是两个可行的专业。让我们来看看当我们尝试实例化 hana::tag_of&lt;int&gt; 时会发生什么。

    1. 填写默认模板参数。在这种情况下,第二个模板参数默认为void,所以我们确实有hana::tag_of&lt;int, void&gt;。
    2. 考虑哪些部分专业化是可行的。在这种情况下,none 是可行的 - 我们的类型 (int) 不是引用或 cv 限定的,也不是任何类型的 when&lt;condition&gt;。由于没有一个专业化是可行的,我们实例化了主模板。
    3. 主tag_of&lt;T, void&gt; 继承自tag_of&lt;T, when&lt;true&gt;&gt;。所以现在我们需要实例化第二种类型,这意味着我们重做第 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>{}()>>
      

      请注意,您的其他专长不可行 - 因为std::is_same&lt;T, unsigned&gt;{} 是false,我们正在尝试匹配when&lt;true&gt;。

    5. 在这两个特化之间,如果我们通过部分排序规则,您的特化会更加特化 - 因此它被选中并实例化。

    因此,hana::tag_of&lt;int&gt;::type 是 hana::tag_of&lt;int, void&gt;::type 是 hana::tag_of&lt;int, when&lt;true&gt;&gt;::type 是 hana::tag_of&lt;int, when&lt;std::is_same&lt;T, int&gt;{}()&gt;&gt;::type 是 my_tag。


    问题是,如果 false 案例没有默认实现,我不明白为什么 when 模板的 true 或 false 值很重要。

    以上内容希望能说明它的重要性。我们没有直接实例化when&lt;false&gt;,但您可以编写一个替代when&lt;false&gt; 的专业化(如您的when&lt;std::is_same&lt;T, unsigned&gt;{}()&gt; 专业化)。

    以及为什么,如果两种情况的条件都是false,when&lt;condition&gt; 更专业。

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


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

    template <>
    struct tag_of<int, void> {
        using type = my_tag;
    };
    

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

    【讨论】:

    • 美得惊人。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-14
    • 2016-02-28
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多