为什么名称空间不能被模板化?

Jak*_*ake 5 c++ standards templates namespaces

我正在开发一个具有多个模板类的库,所有模板类都相互关联,以至于它们都具有相同的模板参数.从某种意义上说,给定的模板参数集描述了一个几乎自包含的类,可能在这些类Universe之间有一条或两条路径.

在当前的C++中,我没有真正的方法将这样的"类宇宙"组合在一起,除非是以相当丑陋和手动的方式.下面是一些相互关联的模板化类的示例,可能会突出我的观点:

template<size_t dimension>
using vector_t = std::array<double, dimension>;

template<typename weight_t, size_t outer_dimension, size_t inner_dimension>
class A{
protected:
    weight_t weight;
public:
    weight_t get_weight(
        const vector_t<outer_dimension>& foo,
        const vector_t<inner_dimension>& bar
    ) const;
};

template<typename weight_t, size_t outer_dimension, size_t inner_dimension>
class B{
protected:
    std::vector<std::shared_ptr<A<weight_t, outer_dimension, inner_dimension>>> A_vector;
};

template<typename weight_t, size_t outer_dimension, size_t inner_dimension>
class C{
protected:
    std::vector<std::shared_ptr<A<weight_t, outer_dimension, inner_dimension>>> A_vector;
    std::vector<std::shared_ptr<B<weight_t, outer_dimension, inner_dimension>>> B_vector;
public:
    typename std::enable_if<
        (inner_dimension > 0),
        C<weight_t, outer_dimension + 1, inner_dimension - 1>
    >::type do_something() const;
};
Run Code Online (Sandbox Code Playgroud)

这是可用的 - 而且,在我正在使用的实际库中,该结构非常适合我想要使用它.另一方面,它非常丑陋,而且非常明确.

如果在C++标准中存在模板化命名空间,我可以做一些更好的事情:

template<size_t dimension>
using vector_t = std::array<double, dimension>;

template<typename weight_t, size_t outer_dimension, size_t inner_dimension>
namespace universe{
    typedef vector_t<outer_dimension> outer_vector;
    typedef vector_t<inner_dimension> inner_vector;

    class A{
    protected:
        weight_t weight;
    public:
        weight_t get_weight(const outer_vector& foo, const inner_vector& bar) const;
    };

    class B{
    protected:
        std::vector<std::shared_ptr<A>> A_vector;
    };

    class C{
    protected:
        std::vector<std::shared_ptr<A>> A_vector;
        std::vector<std::shared_ptr<B>> B_vector;
    public:
        typename std::enable_if<
            (inner_dimension > 0),
            universe<weight_t, outer_dimension + 1, inner_dimension - 1>::C
        >::type do_something() const;
    };
}
Run Code Online (Sandbox Code Playgroud)

当然,C++标准中存在模板化命名空间.有一些真正的hacky方法来解决这个问题,例如"模板化"命名空间.方案包括:

  • 使用typedef使模板的整个点变得多余
  • 在名称空间中包装typedef,使冗余模板的重点更加冗余.
  • 有'类型'结构,比上面两个更优选,但仍然很丑(IMO).

显然,这些解决方案是基本问题的解决方法 - 命名空间不能模板化.是否有一个特定的原因,这个标准没有采用这个标准,还是只是一个尚未提出的(以有效的方式)?

我可以看到各种其他用例 - 例如,有许多通用库,其中很多关注单个typedef模板参数,这可以从一个整体参数中受益.