C ++模板元编程:从模板模板参数继承

时间:2018-06-01 15:06:32

标签: c++ templates template-meta-programming policy policy-based-design

#include <type_traits>

template <typename T1, typename T2, typename is_allocated>
struct mutable_storage {};

template <
    template<typename, typename, typename> class storage_t,
    typename T2           = void,
    typename is_allocated = std::false_type
>
class Buffer : storage_t<Buffer<storage_t,void,void>, T2, is_allocated>
{};



int main() {
    typedef Buffer<mutable_storage> example_buffer;
}

此代码编译(至少使用C ++ 14之后的GNU GCC编译器)。但是,我不喜欢使用的语法

class Buffer : storage_t<Buffer<storage_t,void,void>, T2, is_allocated>

由于它不应该要求Buffer专门化:我希望Buffer被识别为模板模板参数,例如:

class Buffer : storage_t<Buffer, T2, is_allocated>

然后我希望mutable_storage结构识别像

这样的模板特化
template <typename T2, typename is_allocated>
struct mutable_storage<Buffer, T2, is_allocated> { ... };

(当然不允许,因为“缓冲区”不是类型,因此也应该更改)。 但它现在使用的方式,能够专注于类型 缓冲区感觉有点讨厌。使用typedef,例如

 typedef Buffer<storage_t, void, void> Buffer_Policy

也觉得有点讨厌。我正在寻找一种更清洁的方式。我试图制作一个模板模板模板参数,但这会导致模板参数中无限量的额外模板(我不知道模板&lt; ...&gt;到底是如何工作的,所以可能是这样?),如缓冲区继承自需要另一个缓冲区的东西,以便声明storage_t。我也尝试使用隐式类,即inner_storage_t。这也没有导致成功。有没有人有建议,以使程序更清洁?顺便说一句,如果您发现任何其他错误或效率低下,请随意提及。感谢阅读和可能的帮助。

1 个答案:

答案 0 :(得分:2)

由于T1仅用于模板专精选择,因此您不必真正使用Buffer。您可以改用标签类型。

在命名空间中将其删除也可以避免使用标记污染封闭命名空间的其余部分。

#include <type_traits>

template <typename T1, typename T2, typename is_allocated>
struct mutable_storage {};

namespace storage_tags {
  struct Buffer_T {};
}

template <
    template<typename, typename, typename> class storage_t,
    typename T2           = void,
    typename is_allocated = std::false_type
>
class Buffer : public storage_t<storage_tags::Buffer_T, T2, is_allocated> { 

};