1

So I got myself in a pickle with C++ templates. Assuming I got a hierarchy of container-like classes of the form:

template <class T>
class AContainer{
    // ...
};

And through inheritance different containers with different internal representations are made:

template <class T>
class AVectorLikeContainer: public AContainer<T>{
    // ...
};

And a bunch of hierarchies of operator-like classes which have the form:

template <template <class T> class C, class T>
class AnOperator{
public:
    virtual T operator() (const C<T> &c1, const C<T> &c2);
    // ...
};

Using inheritance and partial specialization operators like these are made:

template <class T>
class AnOperatorForVectorLike: public AnOperator<AvectorLikeContainer, T>{
public:
     virtual T operator() (const AVectorLikeContainer<T> &c1, const AVectorLikeContainer<T> &c2);
     // ...
};

Now, a bit later in the project, containers of the form:

template <class T, std::size_t N>
class AStaticSizeContainer: public AContainer<T>{
    // ...
};

were introduced. Obviously this sort of breaks the design, since AStaticSizeContainer doesn't match the template <class T> class C part of the template signature of AnOperator. A way to go around this is to introduce a meta-function like so:

template <class T, std::size_t N>
class StaticSizer{
public:
    template <class T1>
    class SizedStaticContainer: public AStaticSizeContainer<N, T1>{
        // ...
    };
};

This way, StaticSizer<25>::SizedStaticContainer is a class which matches the template signature template <class T> class C. However, this has a few downsides. The first and obvious one is the need to always use StaticSize<N>::SizedStaticContainer<T> instead of AStaticSizeContainer<T, N> even when T and N are "known". This is caused by the fact that the two are not interchangeable (one is inherited from the other). The second downside is that all constructors of AStaticSizeContainer must be literally copy-pasted for StaticSizer::SizedStaticContainer. I'm sure there are more that I've yet to stumble upon.

So, my questions are the following:

Is there a more elegant way to fix this while conforming to the already laid out interface? In broader terms, can we specify a partial specialization of a class in a more elegant way? In narrower terms, do we have the syntax to say something like:

template <class T, std::size_t N>
class AnOperatorForStaticSize: public AnOperator<AStaticSizeContainer<with N = N>, T>{
    // ...
};

where by AStaticSizeContainer<with N = N>, I refer to a partial specialization of AStaticSizeContainer with the N from the above template.

EDIT C++11's alias templates apparently will work, but I need a C++03 alternative.

4

1 回答 1

1

在 C++ 的早期,人们尝试了各种类似的方法,但都没有成功。根据过去近 20 年的经验,可能会设计出更好的方法,但似乎通用编程(以 STL 的形式引入)提供了一个可行的解决方案,它没有您描述的任何问题。解决方案的基本思想是解决计算机科学问题的基本方法:引入额外的间接级别。您可以根据对结构的通用访问方法来实现运算符,而不是将结构与运算符联系起来。在 STL 中,结构是序列,运算符是算法,中间的粘合剂是迭代器。

于 2013-09-15T12:54:39.213 回答