【问题标题】:Partial template specialization outside class definition类定义之外的部分模板特化
【发布时间】:2012-10-04 05:17:42
【问题描述】:

我可以在类声明中使用部分模板特化

template<class T1, class T2>
struct A
{
    void foo() { cout << "general"; }
};

template<class T1>
struct A<T1, int>
{
    void foo() { cout << "partial specialization"; }
};

但是当我试图在类声明之外这样做时

template<class T1, class T2>
struct A
{
    void foo();
};


template<class T1, class T2>
void A<T1, T2>::foo() { cout << "general"; }

template<class T1>
void A<T1, int>::foo() { cout << "partial specialization"; }

我收到以下错误:

不完整类型«struct A »的无效使用

当您想重新定义所有成员时,使用第一种方法没有问题,但是如果您只想重新定义一个方法而不为所有其他方法重复代码怎么办?

那么,是否可以在类定义之外使用部分模板特化?

【问题讨论】:

    标签: c++ templates


    【解决方案1】:

    c++ 标准禁止在没有完全特化外部模板的情况下特化方法。所以是的,这是不可能的。我不确定它是否对 c++11 有效,但我怀疑它是有效的。

    解决此问题的一种方法是专门化外部模板,就像您在第一个示例中所做的那样。

    顺便说一句,这可能是另一种解决方法:

    template<class T1, class T2>
    struct A
    {
        template<unsigned int I>
        void foo() { cout << "general"; }
    
        template<>
        void foo<2> () { cout << "specialization"; }
    
    };
    

    这是可行的,因为这不是专门化的,而是方法的不同模板。

    【讨论】:

      【解决方案2】:

      在你失败的例子中:

      template<class T1>
      void A<T1, int>::foo() { cout << "partial specialization"; }
      

      您指的是尚未定义的 A 的特化(您仅在第二个示例中定义了完整模板)。

      如果在引用之前添加专业化,它确实应该有效:

      template <class T1>
      struct A<T1, int>
      {
        void foo ();
      };
      
      template <class T1>
      void A<T1, int>::foo ()
      {
        /* something */
      };
      

      【讨论】:

        【解决方案3】:

        当你想重新定义所有成员时使用第一种方法没有问题,但是如果你想只重新定义一个方法而不为所有其他方法重复代码怎么办?

        这是可以使用特征技术的地方。见http://www.boost.org/community/generic_programming.html#traits

        一些用法:

        template <class T1, class T2>
        struct ATraits {
           static void foo() {}
        };
        
        template <class T1>
        struct ATraits<T1,int> {
           static void foo() {}
        };
        
        template <class T1, class T2>
        struct A {
           void foo() { ATraits<T1,T2>::foo(); }
        };
        

        【讨论】:

          【解决方案4】:

          这里讨论了相同的主题: "invalid use of incomplete type" error with partial template specialization

          +1 用于 tozka 的解决方案,如果 A 除了 foo() 之外不需要知道 I,这是一个很好的解决方法。否则,请查看上面提到的问题的答案。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-12-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多