启用 if/else 类成员模板实例化
Enable if/else class member template instantiation
谁能告诉我如何基于预定义基集中的不同派生类启用 if/else 类成员模板?让我使用以下示例:
enum class Type {
TYPEA,
TYPEB
};
// Predefined in libraries.
class BaseA {...};
class BaseB {...};
class Foo {
template <typename Derived, Type type>
void foo();
};
// User-derived
class DerivedA : public BaseA {};
class DerivedB : public BaseB {};
通常我们需要两个模板类型名来调用成员 foo。
Foo obj;
obj.foo<DerivedA, Type::TypeA>()
obj.foo<DerivedB, Type::TypeB>();
然而,这种原生方法似乎很长,因为第二个模板参数Type::TypeA
和Type::TypeB
显然可以通过编译器通过第一个参数DerivedA
和DerivedB
推导出来,如果它们正确地从预定义的基派生。我注意到 c++11 提供了is_base_of
模板,但我不确定如何在我的情况下使用它。更具体地说,以下是预期的解决方案:
obj.foo<DerivedA>(); // Automatically deduce type = Type::TypeA
obj.foo<DerivedB>(); // Automatically deduce type = Type::TypeB
如果编译无法从第一个类型名推断出Type
,它应该返回到正常的声明obj.foo<MyClass, MyType>
,其中MyType
要么Type::TypeA
要么Type::TypeB
。
听起来你只需要一个默认的模板参数:
class Foo {
template <typename Derived, Type type = get_type_from<Derived>::value>
void foo();
};
其中get_type_from<>
是一个元函数,稍后将根据您实际计算Type
的方式填充。
template<Type t>
using etype_tag = std::integral_constant<Type, t>;
template<class T>
struct tag_t {
using type=T;
template<class D,
std::enable_if_t<std::is_base_of<T, D>::value, int>* =nullptr
>
constexpr tag_t( tag_t<D> ) {}
constexpr tag_t() = default;
constexpr tag_t(tag_t const&) = default;
};
template<class T>
constexpr tag_t<T> tag{};
constexpr etype_tag<Type::TYPEA> get_etype( tag_t<BaseA> ) { return {}; }
constexpr etype_tag<Type::TYPEB> get_etype( tag_t<BaseB> ) { return {}; }
template<class T>
constexpr decltype( get_etype( tag<T> ) ) etype{};
现在etype<Bob>
是您想要的编译时常量整数常量。
class Foo {
template <typename Derived, Type type=etype<Derived>>
void foo();
};
使第二个参数(通常)是多余的。
您可以在声明 etype
的命名空间中,或在 tag_t
的命名空间中,或者在要扩展get_etype
要使用的类型的命名空间中使用更多重载来扩展get_etype
,etype
将自动获得支持(假设它在扩展可见的上下文中使用): 如果满足该要求,您的程序格式不正确)。
现场示例
相关文章:
- 静态数据成员模板专用化的实例化点在哪里
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 受约束的成员函数和显式模板实例化
- 实例化多种类型的成员函数模板
- 为什么在使用指针时不采用类成员的默认值,而不是直接实例化对象时?
- 将类成员函数的模板定义放在 CPP 文件中C++隐式实例化而不是 .H 允许吗?
- 如何实例化类的公共成员并将其作为 std::p romise 返回?
- 在实例化封闭类模板之后,我们可以声明模板类成员的部分专用化吗
- 使用 SFINAE 有选择地实例化模板的成员函数
- 静态模板成员函数的实例化?
- 访问使用接口实例化的类的私有成员
- Google Mock:在目标类的构造函数中实例化的模拟私有变量成员
- 参考数据成员到模板的实例化
- 类的私有成员在我的类实例化期间更改,即使他们不应该
- 如果未实例化成员模板,是否要评估static_asserts?
- 实例化与unique_ptr的类集合成员
- 实例化成员模板函数时的Buggy(?)编译器行为
- 类模板的成员函数模板找不到定义,尽管存在显式实例化。不链接
- 如何实例化C++成员字符串引用
- 通过模板参数选择子类与实例化成员变量的区别