【问题标题】:Using CRTP with partial class specialization?使用具有部分类专业化的 CRTP?
【发布时间】:2018-06-03 20:53:21
【问题描述】:

我正在尝试将 operator [] 与课程混合。我的问题是我已经部分专门化了这个类,编译器不喜欢我不给派生类指定模板参数:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
struct mixin {
    template <typename U>
    void operator[](U u) {
        cout << u;
    }
};


template <typename T, typename = void>
struct derived : mixin<derived> {};


template <typename T>
struct derived<T, 
    typename enable_if<
        is_same<T, int>{}
    >::type> : mixin<derived> {};


int main() {
    derived<int> d;
    d[3.14];
}

用 clang 这给出了:

test.cc:16:24: error: use of class template 'derived' requires template arguments
struct derived : mixin<derived> {};
                       ^~~~~~~
test.cc:16:8: note: template is declared here
struct derived : mixin<derived> {};
       ^
test.cc:23:22: error: use of class template 'derived' requires template arguments
    >::type> : mixin<derived> {};
                     ^~~~~~~
test.cc:16:8: note: template is declared here
struct derived : mixin<derived> {};
       ^

gcc 的帮助更小:

test.cc:16:31: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct mixin’
 struct derived : mixin<derived> {};
                               ^
test.cc:16:31: note:   expected a type, got ‘derived’
test.cc:23:29: error: type/value mismatch at argument 1 in template parameter list for ‘template<class T> struct mixin’
     >::type> : mixin<derived> {};
                             ^
test.cc:23:29: note:   expected a type, got ‘derived’
test.cc: In function ‘int main()’:

我唯一的选择是在 mixin 子句中重新指定模板参数吗?

【问题讨论】:

  • 如果你的 mixin 只是在 U 上模板化的方法,为什么还需要在 T 上模板化?
  • 我没有把它放在这里,但我需要降级回基类,这让我很头疼......

标签: c++ c++11 templates template-meta-programming


【解决方案1】:

好吧,试试这个:

#include <iostream>
#include <type_traits>

using namespace std;

template <typename T>
struct mixin {
    template <typename U>
    void operator[](U u) {
        cout << u;
    }
};


template <typename T, typename = void>
struct derived : mixin<derived<T>> {};


template <typename T>
struct derived<T,
    typename enable_if<
        is_same<T, int>::value
    >::type> : mixin<derived<T>> {};


int main() {
    derived<int> d;
    d[3.14];
}

work...

我改变了什么:

  1. 使用is_same&lt;foo,bar&gt;::value,而不是is_same&lt;foo,bar&gt;{} 编辑: 嗯,看来您毕竟不需要更改它。整洁!
  2. 在使用mixin&lt;derived&gt; 时,不试图让编译器推导出派生的模板参数。你在那儿方式太乐观了......

【讨论】:

  • 像这样显式传递类型确实有效(幸好不必包含整个 enable_if 子句),但我很难过我不能使用注入的名称。
  • @SeanMcAllister:我认为这里甚至没有尝试模板参数推导,尽管 IANALL。
  • 耻辱。顺便说一句, is_same<...>{} 技巧之所以有效,是因为它实例化了 is_same ,它是 true_type 或 false_type 所以 {} 给你 true 或 false =D
  • 我的想法不是推断演绎,而是使用注入的名称。在类的主体中,类型上下文中的every_实际上意味着_
  • @SeanMcAllister:“在两个班级中”可能是您评论中的关键词。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-26
  • 2012-03-18
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多