【问题标题】:Specialization of template method in partial class specialization部分类特化中模板方法的特化
【发布时间】:2012-02-10 18:21:18
【问题描述】:

有这个代码:

#include <iostream>
#include <string>
#include <typeinfo>

// template class
template <class U, class X, class T>
class Klasa{
public:   
    template <class Z>
    void Method(){
    }
};

// partial class specialization
template <class U>
class Klasa<U, int, U>
{
public: 
    // template method
    template <class Z>
    void Method(){
    }
};

// error occurs for that!
template <class U>
template <>
void Klasa<U, int, U>::Method<int>(){
}

int main() 
{ 
    Klasa<float, int, float> object;
    object.Method<float>();
    return 0;
} 

编译错误:

error: invalid explicit specialization before ‘>’ token
error: enclosing class templates are not explicitly specialized
error: template-id ‘Method<int>’ for ‘void Klasa<U, int, U>::Method()’ does not match any template declaration

我尝试对方法进行专业化

void Klasa<U, int, U>::Method<int>

,但是编译器不接受它。这个方法的特化怎么写?

【问题讨论】:

标签: c++ templates


【解决方案1】:

我了解,对于 Klasa&lt; U, X, T &gt; 的每个部分专业化,您都想“专业化”(重载,真的,没有功能(编辑:部分)专业化(编辑:您实际上试图实现))@987654323 @ 只输入一次 X。这是代码(ideone link),看看是否是你需要的。此外,您可能真的想考虑一些有助于消除重复的特征类(我假设 Method() 对于所有通用 Klasa&lt; U, X, T&gt; 都是相同的,并且您需要为类型 X 的特定特化提供额外的实现)。编辑:也许,我应该提一下,尝试使用Method&lt; int &gt;() 时会出现编译错误。假设该类的用户理解他需要调用Klasa&lt; U, X, T &gt;::Method() 来获得Method&lt; Z &gt;() 的X“专业化”。

#include <iostream>

template< class U, class X, class T >
class Klasa
{
  public:
    template< typename Z >
    void Method()
    {
    }
};

template< class U >
class Klasa< U, int, U >
{
  public:
    template< typename Z >
    void Method()
    {
      typedef typename std::enable_if< !std::is_same< int, Z >::value, Z >::type whatever;

      std::cout << "Method< Z >" << std::endl;
    }
   void Method()
    {
      std::cout << "Method< int >" << std::endl;
    }
};

int main()
{
  Klasa< float, int, float > lK;

  lK.Method< float >();
  lK.Method< double >();
  lK.Method();

  return( 0 );
}

程序输出:

Method< Z >
Method< Z >
Method< int >

【讨论】:

  • "重载,真的,没有函数特化" 有函数模板特化,只是没有部分函数模板特化。
  • @ildjarn 我猜,措辞不好。我的意思是,在上下文中“没有功能专业化”。 Klasa&lt;U, int, U&gt;::Method&lt; int &gt; 是部分专业化,当然,你是绝对正确的。
【解决方案2】:

不要向我询问确切的报价,但根据 David Vandevoorde 的说法,这是不可能的。基本原理是,这本质上是函数模板的部分特化,没有这样的东西。不允许这样做的一个原因是,如果类有进一步的特化,则不清楚这种特化会发生什么:函数特化是继承的还是不继承的?

显然,说明这不能完成并没有多大帮助。可以做些什么呢?一种简单的方法是将实现委托给重载的私有实现,例如用于消除各种类型之间歧义的指针参数。我意识到重点可能是避免使用额外的参数,即使它只是在内部使用。另一种可能的方法是使用完全特化的基类:this 的成员函数模板可以显式特化。

【讨论】:

    猜你喜欢
    • 2012-05-04
    • 2019-09-06
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 2012-11-06
    • 1970-01-01
    • 1970-01-01
    • 2017-08-13
    相关资源
    最近更新 更多