按类型检索可变类的给定成员
Retrieve given member of variadic class by type
这是一个递归类定义:
template<class... T>
class Mgr2
{
};
template<class T, class... args>
class Mgr2<T, args...>
{
Container<T> _container;
Mgr2<args...> _tail;
public:
Mgr2() { };
};
我想实现以下内容:
Mgr2<int, double> mgr;
mgr.get<int>(); // retrieves the Container<int> element
我怎么能这么做?我试着做几件事,但失败了....自由函数也很好,如果在类定义中有2个"int",我不在乎行为是否未定义,例如
谢谢!
这里有一种方法的草图,通过重组Mgr2
:
template<class T>
struct Leaf {
Container<T> container;
};
template<class... Ts>
struct Mgr2 : Leaf<Ts>... {
template<class T>
Container<T> &get() {
return static_cast<Leaf<T>&>(*this).container;
}
};
一旦实例化Mgr2
,具有重复类型就会导致编译时错误。
如果我们想允许重复,或者除了按类型索引外,还允许按整数索引,我们可以在Leaf
中添加索引参数:
template<std::size_t I, class T>
struct Leaf {
Container<T> container;
};
和调整Mgr2
:
template<class Seq, class...> struct Mgr2_Impl;
template<std::size_t... Is, class... Ts>
struct Mgr2_Impl<std::index_sequence<Is...>, Ts...>
: Leaf<Is, Ts>... { };
template<class... Ts>
struct Mgr2 : Mgr2_Impl<std::index_sequence_for<Ts...>, Ts...> {
private:
template<class T, std::size_t I>
Leaf<I, T>& do_get(Leaf<I, T>& leaf) { return leaf; }
template<std::size_t I, class T>
Leaf<I, T>& do_get(Leaf<I, T>& leaf) { return leaf; }
public:
template<class T>
decltype(auto) get() { return do_get<T>(*this).container; }
template<std::size_t I>
decltype(auto) get() { return do_get<I>(*this).container; }
};
如果你想保持你的原始设计,你可以使用SFINAE或标签调度。显示前者:
template<class U>
std::enable_if_t<std::is_same<U, T>{}, Container<U>&> get(){
return _container;
}
template<class U>
std::enable_if_t<!std::is_same<U, T>{}, Container<U>&> get(){
return _tail.template get<U>();
}
与std::tuple
, std::get
from c++ 14:
template<typename... Ts>
class Mgr2
{
private:
std::tuple<Container<Ts>...> _containers;
public:
Mgr2() {};
template <typename T>
const Container<T>& get() const { return std::get<Container<T>>(_containers); }
template <typename T>
Container<T>& get() { return std::get<Container<T>>(_containers); }
};
演示。
如果你坚持使用c++ 11,你可以用c++ 11编写自己的get<T>
。
我发现这样做很容易:
template<class... T>
class CptMgr
{
};
template<class T, class... args>
class CptMgr<T, args...>
{
CptContainer<T> _container;
CptMgr<args...> _tail;
public:
template<class U>
CptContainer<U>& get() { return _tail.get<U>(); };
template<>
CptContainer<T>& get() { return _container; };
}
相关文章:
- 根据模板类型选择类模板的成员类型?
- 函数模板签名中忽略的成员类型def 的访问说明符
- 在C++如何从数组中提取成员并返回成员类型的数组?
- C++从成员类型中扣除类型的功能模板?
- 无法初始化以 std::byte 作为成员类型的位字段
- 构造函数可以更改默认成员类型吗?
- 使用相同方法但不同成员类型构建类的最佳方法
- 允许通过指向方法的成员参数的指针来推断模板参数所指向的成员类型
- 使用 std::条件根据模板参数选择成员类型
- CRTP:如何推断要用作返回类型的成员类型?
- 对成员类型的成员方法使用 std::result_of<>
- C :可以从类及其受保护的成员类型继承可以继承吗?
- 如何在不指定不必要的模板参数的情况下使用模板类的成员类型
- 基类数据成员类型取决于派生类
- C 多态性:允许模棱两可的成员类型
- 使用使用成员类型别名的构造函数来推论类模板参数
- 获取与在模板参数中传递的函数成员类型相同的类
- 如果静态成员未初始化并且成员类型是类本身,该怎么办?
- boost::bind 无法绑定到纯虚拟基类中定义的非静态函数模板成员类型
- 将联合强制转换为其成员类型之一