嵌套的模板类,带有std::enable_if,C++

bxgwgixi  于 2024-01-09  发布在  其他
关注(0)|答案(1)|浏览(121)

我有一个模板类B,它的第一个参数T1必须继承类A,第二个参数T2在嵌套类C中使用:

  1. class A { ... };
  2. template<typename T1, typename T2 = T1, typename = std::enable_if_t<std::is_base_of<A, T1>::value>>
  3. class B {
  4. class C {
  5. T2 data;
  6. C(T2 data);
  7. void func();
  8. ...
  9. };
  10. ...
  11. };

字符串
问题是,当我尝试定义嵌套类的构造函数和方法时,我会得到错误:

  1. template<typename T1, typename T2, typename>
  2. B<T1, T2>::C::C(T2 data) : data(data) { ... }
  3. template<typename T1, typename T2, typename>
  4. void B<T1, T2>::C::func() { ... }

  1. E0464“B<T1,T2,std::enable_if_t<std::is_base_of<A,T1>::value,void>>::C”不是类模板;
  2. C3860类类型名称后面的类型参数列表必须按照类型参数列表中使用的顺序列出参数。
    如果我不使用嵌套类或不使用std::enable_if,代码可以正常工作,但在这里我需要它们,我真的不明白什么是错的。
t1rydlwq

t1rydlwq1#

在定义构造函数时,仍然需要提供默认的模板参数:

  1. template<typename T1, typename T2, typename D>
  2. B<T1, T2, D>::C::C(T2 data) : data(data) { }

字符串
请注意,在C内部定义构造函数会更好。无论如何,大多数情况下都不能将模板拆分为header/source,并且处理类模板的离线定义可能非常烦人和脆弱。

C17和C20的注意事项

如果你使用C++20,你可以写:

  1. template<std::derived_from<A> T1, typename T2 = T1>
  2. class B { /* ... */ };
  3. template<std::derived_from<A> T1, typename T2>
  4. B<T1, T2>::C::C(T2 data) : data(data) { }


如果你使用的是C++17,你至少可以使用辅助变量模板std::is_base_of_v<A, T1>

展开查看全部

相关问题