Inner class depending on a template argument

会有一股神秘感。 提交于 2019-12-04 18:09:29

You can't define C outside B this way - C doesn't exist for the B specialization you're creating. If you want to specialize B::C, you need to specialize B. Are you trying to do the following?

template< int N, typename T >
struct B
{
    struct C {
        typedef T type[N];
    };
};

template< typename T >
struct B< 0, T >
{
    struct C {
        typedef T type;
    };
};

Alternatively, you can do something like:

template< int N, typename T >
struct B
{
    struct C;
};

template< typename T >
struct B< 0, T > {
    struct C;
};

template< typename T >
struct B< 0, T >::C
{
    typedef T type;
};

template< int N, typename T >
struct B< N, T >::C
{
    typedef T type[N];
};

This partially specializes B for 0 and forward declares C, so that B<0, T>::C can be defined.

This is not valid:

template< typename T >
struct B< 0, T >::C
{
    typedef T type;
};

You can specialize members of class templates, but only for implicit instantiations of those class templates. This means in plain English: Only if you give values for all the template arguments of the enclosing class template (whose member you need to specialize).

template< >
struct B< 0, int >::C
{
    typedef T type;
};

What you wrote is the definition of a B<0, T>::C, which is a member of a class template partial specialization of B<N, T>. Such a partial specialization does not exist, therefor, the compiler errored out.


You have several options to solve this. One is

template< int N, typename T >
struct B
{
    template<typename N1, typename T1>
    struct CMember { typedef T1 type[N1]; };

    template<typename T1>
    struct CMember<0, T1> { typedef T1 type; };

    struct C { 
      typedef typename CMember<N, T>::type type;
    };
};

Note that explicit specializations (non-partial) cannot be put into the class template directly (so, template<> struct CMember<0, int> { ... } would be ill-formed when writting inside the body of B). You would need to define the "selector" template outside B then (perhaps in a detail namespace).

Other alternatives include deriving from CMember and inheriting its typedefs.

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