我有一堂课,看起来像这样:
template<class KeyType, class... Types>
class BasicCompound
{
public:
using mapped_type = std::variant
<
ValueWrapper<BasicCompound>
, ValueWrapper<Types>...
>;
using key_type = KeyType;
// Accessors for retreiving and modifying content
// ...
private:
std::map<key_type, mapped_type> m_content;
};
ValueWrapper
决定将内容放入行内或放在std::unique_ptr
中。是否可以通过类似的接口(可能通过某种代理)将递归性设置为可选?通过可选,我的意思是用户不应自动获得将BasicCompound
存储在其内部的可能性,而应在类型列表中进行指定。
我的想法:
using
指令不起作用。不能在其自身中定义新类型,并且不允许预先声明以下typedef。bool
添加到类型列表,并将std::conditional_t
用于mapped_type
。但是,如果用户要存储X<BasicCompound>
,则此方法将失败。mapped_type
。然后,我无法隐藏ValueWrapper
东西的使用。在typdef
上使用继承,例如
struct MyCompound : BasicCompound<std::string, MyCompound, int> {};
这可行,但是结构不是严格递归的,因为MyCompound
现在是与BasicCompound
不同的类型。也许类似CRTP的方法可以解决该问题,但是内部化合物类型必须与其他类型区别对待。
答案 0 :(得分:0)
您不能将类模板的特殊化用作该特殊化的模板参数之一;没有办法写,它的名字会无限长。但是,您可以使用包装器来保存递归类型:
template<class> class MaybeRecursive;
template<class T>
struct Wrapper {
using type=T;
};
struct MRWrapper {
using type=MaybeRecursive<MRWrapper>;
};
template<class T>
struct MaybeRecursive {
using type=typename T::type;
type *child;
};
void f() {
int x;
MaybeRecursive<Wrapper<int>> nonrec={&x};
MRWrapper::type rec={&rec};
}
可以将 MRWrapper
用作类模板,以为MaybeRecursive
提供附加的模板参数。