问题描述
请考虑以下tree
类
template<typename T, template<typename> class Tuple>
class tree
{
private:
T m_value;
Tuple<tree> m_children;
};
template<typename T, std::size_t N>
using static_tree = tree<T, std::array<T, N>>;
这是没有明确定义的. std::array<T, N>
不是Tuple
的合适模板参数.我认为static_tree
的意图很明确.我们可以做类似的事情
which is not well-defined. std::array<T, N>
is not a suitable template parameter for Tuple
. I assume the intend of static_tree
is clear. We could do something like
template<std::size_t N>
struct helper
{
template<typename T>
using type = std::array<T, N>;
};
template<typename T, std::size_t N>
using static_tree = tree<T, helper<N>::template type>;
如果没有helper
类,还有其他选择吗?
Is there any other option without the helper
class?
推荐答案
我建议这是规则,而不是让helper函数成为std::array
的例外.代替采用模板template参数,而采用元函数类参数.当所有内容都是类型时(避免模板模板和非类型参数),模板元编程会容易得多:
Rather than having the helper function be an exception for std::array
, I'd propose that be the rule. Instead of taking a template template parameter, take a metafunction class parameter. Template metaprogramming is a lot easier when everything everywhere is a type (avoiding template templates and non-type arguments):
template<typename T, typename TupleMfn>
class tree
{
private:
using Tuple = TupleMfn::template apply<tree>;
T m_value;
Tuple m_children;
};
具有:
template <size_t N>
struct array_builder {
template <class T>
using apply = std::array<T, N>;
};
template <typename T, size_t N>
using static_tree = tree<T, array_builder<N>>;
这也将使它更易于与其他类型的容器一起使用,因为我们可以为模板模板做一个包装,从而为我们提供一个元功能:
This will make it easier to use with other kinds of containers as well, since we can make a wrapper for template templates that gives us back a metafunction:
template <template <typename...> class X>
struct as_metafunction {
template <class... Args>
using apply = X<Args...>;
};
template <typename T>
using vector_tree = tree<T, as_metafunction<std::vector>>;
如果您特别讨厌,可以提供std::array
的元编程友好版本:
If you're feeling especially feisty, you can provide a metaprogramming-friendly version of std::array
:
template <class T, class N>
struct meta_array : std::array<T, N::value> // obviously I am terrible at naming things
{ };
template <size_t N>
using size_t_ = std::integral_constant<size_t, N>;
然后为tree
提供占位符args:
And then provide placeholder args for tree
to apply:
template <class T, size_t N>
using static_tree = tree<T, meta_array<_, size_t_<N>>>;
template <class T>
using vector_tree = tree<T, std::vector<_>>;
这篇关于如何将`std :: array`用于形式为`template< typename>班级?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!