【问题标题】:Specialization of nested template class inside template class after its declaration声明后模板类内部嵌套模板类的特化
【发布时间】:2019-07-01 10:25:29
【问题描述】:

我有自己的布尔类型的定义

template<bool b>
struct Bool {
    constexpr static bool value = b;
};

using True = Bool<true>;
using False = Bool<false>;

我正在尝试获取类 Eq 的 haskell Bool 实例。

template<typename T>
struct Eq {
    template<typename R>
    struct equal;

    template<typename R>
    struct notEqual {
        using value = typename not_<typename equal<T, R>::value>::value;
    };
};

我想知道,如何对“equal”类进行专门化。更清楚地说,我想要这样的东西:

template<bool a>
template<bool b>
struct Eq<Bool<a>>::equal<Bool<b>> {
    using value = typename std::conditional<a == b, True, False>::type;
};

有解决办法吗?我试图做到这一点:

template<bool a>
struct Eq<Bool<a>>::equal<Bool<a>> {
    using value = True;
};

但是编译器告诉我“'mtp::Eq&lt;T&gt;::equal':模板参数太多”。感谢您的帮助。

【问题讨论】:

标签: c++ templates metaprogramming


【解决方案1】:

您不能专注于像 Bool&lt;a&gt; 这样的依赖模板。以下将起作用:

template<typename T>
template<bool b>
struct Eq<T>::equal<Bool<b>> {
    using value = /* ... */;
};

您可以使用std::enable_if_t 来确保T 是Bool,并使用另一个模板来提取该Bool 类型的值。

live example on godbolt

【讨论】:

    【解决方案2】:

    如果你想部分特化Eq&lt;Bool&lt;a&gt;&gt;::equal&lt;Bool&lt;b&gt;&gt;,你必须分几个部分来做:

    template <bool b>
    struct Eq<Bool<b>> {
        template<typename R>
        struct equal;
    
        template<typename R>
        struct notEqual {
            using value = typename not_<typename equal<T, R>::value>::value;
        };
    };
    

    然后

    template<bool a>
    template<bool b>
    struct Eq<Bool<a>>::equal<Bool<b>> {
        using value = typename std::conditional<a == b, True, False>::type;
    };
    

    Demo

    【讨论】:

    • 问题是 struct "notEqual" 对于所有实例都是相同的,要么是 bool,要么是其他任何东西。我想避免为每种类型编写它的定义。
    • 为什么没有template &lt;typename LHS, typename LHS&gt; struct equal;,你可以根据需要进行部分专业化,然后struct Eq::equal 只转发到这个struct。
    • template&lt;typename T&gt; struct Eq { template &lt;R&gt; using equal = std::is_same&lt;T, R&gt;; }; 就足够了 IMO,(或 std::conditional_t&lt;std::is_same&lt;T, R&gt;, True, False&gt;; 使用您的类型作为结果)。无需专业化。
    • 我想这是布尔类型的绝佳解决方案。但是如果我想通过计算哈希来比较两个字符串呢?比较规则可以是任何东西,所以我认为std::is_same 不适合这里
    • 正如我所说,(非内部)template &lt;typename LHS, typename LHS&gt; struct equal 似乎更适合您的需要。 (如果你想要的话,你可以用struct Eq 包裹它)。
    猜你喜欢
    • 1970-01-01
    • 2018-11-26
    • 2016-01-11
    • 2015-07-29
    • 2019-03-23
    • 1970-01-01
    • 2015-11-14
    • 1970-01-01
    • 2011-01-30
    相关资源
    最近更新 更多