Syntax for specialization of nested template class

非 Y 不嫁゛ 提交于 2019-11-27 03:20:43

问题


I'm trying to figure out the correct syntax for explicit specialization of a nested template class. The following code will better illustrate:

struct Column_Major;
struct Row_Major;

template<size_t rows, size_t cols, typename T, typename Allocator>
class Matrix
{

    /* bunch of members */
    template <typename storage = Column_Major>
    class Iterator
    {
        /* bunch of members */
    };
};

I'd like to write an explicit specialization for template <> class Matrix<...>::Iterator<Row_Major, but the syntax is eluding me. I have a suspicion that it is not possible to explicitly specialize the Iterator class without an explicit specialization of the containing class, Matrix. But I would be very happy if there is a way to do this.

I know I could make the Iterator class a separate class, not a member of the Matrix class, but having the classes nested as such allows me full access to the template parameters and datamebers of the Matrix class, which simplifies things. I know I could work around this if I need to, but I'd first like to investigate and understand the possibilities for the nested approach.

Thanks, Shmuel


回答1:


For explicit specialization, you need to specialize the outer class before the inner, you can see this question for example.

There is a workaround that is using partial specialization:

template<size_t rows, size_t cols, typename T, typename Allocator>
class Matrix
{

    //                           Notice the additionnal dummy parameter
    //                                       vvvvvvvvvvvvv
    template <typename storage = Column_Major, bool = true>
    class Iterator
    {
    };

    // Specialization
    template <bool dummy>
    class Iterator<Row_Major, dummy>
    {
    };
};



回答2:


You can make Synxis answer (use of defaulted dummy parameter) even more clean with C++11:

/// template <typename X>, not needed for the example
struct Outer
{
private:
    template <typename A, typename D = void>
    struct Inner
    {
        Inner()  { cout << "default" << endl; }
    };
    template <typename D>
    struct Inner<int,D>
    {
        Inner()  { cout << "int" << endl; }
    };  
public:
    template <typename T>
    using  Nested = Inner<T>;
};

The advantage of this improvement is that the signature of Nested has only one template parameter, which I think will help if you want to match it correctly in template meta-programming.




回答3:


I'm surprised the template parameter for the nested class isn't a parameter of the parent class instead.

The nested class can use the template parameters of the parent and this more closely ties the nested class to the parent. Your use of the word iterator suggests this is good, the iterator surely iterating over the same type the parent contains?

I'd do it like this:

template <class T>
class Outer
{
public:
    class Inner
    {
        void Fn( T in )
        {
        }
    };
};

// specialisation
void Outer<double>::Inner::Fn( double in )
{

}


来源:https://stackoverflow.com/questions/19663640/syntax-for-specialization-of-nested-template-class

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!