代码之家  ›  专栏  ›  技术社区  ›  Potatoswatter

专门化成员模板而不专门化其父模板

  •  10
  • Potatoswatter  · 技术社区  · 15 年前

    我有一个类模板嵌套在另一个模板中。部分专业化很容易:我只是声明另一个 template< … > 阻止在其父级中。

    但是,我需要另一个部分专门化,它恰好指定它的所有本地模板参数。这使得它成为一个显式的专门化。无论出于什么原因,显式专用化必须在命名空间范围内。要在其父类之外声明它,必须指定父类,这需要一个非空的模板参数列表。这意味着部分专业化。部分专业化 我正在做的,它应该在任意的外部范围内工作。但是,GCC和COMEAU都未能用部分专门化的形式参数识别父提名中的模板参数。

    template< class X > struct A {
        template< class Y > struct B; // initial declaration OK
    
        template< class Z >
        struct B< A< Z > > {}; // partial OK as long as there's a local arg
    
        template<> // ERROR: this syntax triggers explicit specialization
        struct B< int > {};
    };
    
    template<> // ERROR: can't nest template<>s here (why?)
    template< class X > // ERROR: can't deduce X from type of A<X>::B<int> (why?)
    struct A< X >::B< int > {};
    

    (我把所有不工作的代码都放在里面;对其进行适当的注释,以使其有意义。)

    4 回复  |  直到 15 年前
        1
  •  9
  •   user213546    15 年前

    在C++标准下是非法的:

    ….声明不应明确指定类成员。 模板(如果其封闭类模板未显式专用化) 也。

        2
  •  4
  •   Matthieu M.    15 年前

    我不太喜欢使用嵌套类。我的主要抱怨是它们有膨胀嵌套类代码的倾向。

    因此,我建议另一种解决方法:

    namespace detail
    {
      template <class X, class Z> class BImpl;
      template <class X, class Z> class BImpl<X, A<Z> > {};
      template <class X> class BImpl<X,int> {};
    }
    
    template <class X>
    class A
    {
      template <class Z> struct B: BImpl<X,Z> {};
    };
    

    请注意,它需要将x作为参数传递给 BImpl 如果你还想专攻 A . 有趣的是,在这种情况下,我最终只得到了部分专业化!

        3
  •  0
  •   Terry Mahaffey    15 年前

    复杂的东西。你最初的代码是Ice的VC10 Beta2,不错。

    首先,我认为你是在倒退:

    template<> 
    template< class X > 
    struct A< X >::B< int > {};
    

    x是结构a的模板参数,b是完全专用的模板参数,所以我认为应该是:

    template< class X > 
    template<> 
    struct A< X >::B< int > {};
    

    但即使这样也无法编译。错误文本实际上很有用,但是:

    A.cpp A.cpp(11):错误C3212: “A::B”:显式 模板成员的专门化 必须是显式的成员 专业化 A.cpp(8):见“A::B”声明

    看起来只有当你也完全专攻A的时候,完全专攻B才是合法的。

    编辑 好的,我从一位权威人士那里听说过这一说法,这是标准中一个非常模糊的领域,它是一个开放的问题,C++委员会来清理它(“它”是对类模板成员的明确的专门化)。短期内,建议是“不要这样做”。

        4
  •  0
  •   Jagannath    15 年前

    这至少在VC 2010中有效。但是,我不能写DEF。of fun()表示类声明之外的“int”。 编辑:不幸的是,G++也有编译问题。 编辑:以下代码适用于VC 2010。

    template<typename X>
    class A
    {
    public:
        A()
        {
    
        }
    
        template<typename Y>
        struct B
        {
            void fun();
        };
    
        template<>
        struct B<int>
        {
            void fun()
            {
                cout << "Specialized version called\n";
            }
            //void fun();
        };
    
    
    
    public:
    
        B<X> b;
    };
    
    
    
    template<typename X>
    template<typename Y>
    void A<X>::B<Y>::fun()
    {
        cout << "templated version called\n";
    }
    
    int main()
    {
       A<int> a;
        a.b.fun();
        A<float> a1;
        a1.b.fun();
    }