模板类的模板成员专业化

时间:2012-02-24 15:30:30

标签: c++ templates specialization

我有一个类结构

template<int T>
class MyClass {
public:
    MyClass(){};
    ~MyClass(){};

    template<class K> void foo();
};

现在我想根据foo()中使用的整数值来专门化MyClass<int>方法,例如,如果我们拥有MyClass<2>的代码,我想使用不同的版本如果我有foo<K>(),则为MyClass<3>。不过,我希望foo<K>()上的K仍然未经专业化。

所以这意味着这样的事情就可以了

MyClass<2> myc2;
MyClass<3> myc3;
myc2.foo<SomeClass>();
myc2.foo<SomeOtherClass>();
myc3.foo<SomeClass>();
myc3.foo<SomeOtherClass>();

是否有可能以这种方式专攻但不专注于K?我尝试了几种组合但没有成功。

5 个答案:

答案 0 :(得分:2)

如果我理解你的问题,这就是你想要的:

template<int T>
class MyClass {
public:
    MyClass(){};
    ~MyClass(){};

    template<class K> void foo();
};

template<int T>
template<class K>
void MyClass<T>::foo()
{
    std::cout << "general form\n";
}

template<>
template<class K>
void MyClass<2>::foo()
{
    std::cout << "MyClass<2>\n";
}

int main()
{
    MyClass<3> c1;
    c1.foo<int>(); // general form
    MyClass<2> c2;
    c2.foo<int>(); // MyClass<2>
    c2.foo<float>(); // MyClass<2>
}

答案 1 :(得分:1)

您可以尝试使用boost :: enable_if,它允许启用或禁用类和方法的特定特化。看一下这里的示例:http://www.boost.org/doc/libs/1_48_0/libs/utility/enable_if.html

答案 2 :(得分:1)

这适用于我的Visual C ++ 2010:

template<int T>
class MyClass {
public:
    MyClass(){};
    ~MyClass(){};
    template<class K> void foo() {
        std::cout << "foo() for T" << std::endl;
    }
};

template<>
template<class K>
void MyClass<2>::foo() {
    std::cout << "foo() for 2" << std::endl;
}

template<>
template<class K>
void MyClass<3>::foo() {
    std::cout << "foo() for 3" << std::endl;
}

void main() {
    MyClass<1>().foo<int>();
    MyClass<2>().foo<float>();
    MyClass<3>().foo<std::string>();
}

打印:

foo() for T
foo() for 2
foo() for 3

答案 3 :(得分:-1)

不专业。只需将对重载函数的调用委托为:

template<int T>
class MyClass {
public:
    MyClass(){};
    ~MyClass(){};

    template<class K> 
    void foo()
    {
      foo_worker(static_cast<K*>(0)); //delegate to overloaded function
    }
private:
    template<class K>
    void foo_worker(K*)
    {
        //general code goes here
    } 
    void foo_worker(SomeClass*)
    {
        //code when K = SomeClass
    } 
    void foo_worker(SomeOtherClass*)
    {
        //code when K = SomeOtherClass
    } 
};

以下是它的工作原理:

  • 如果KSomeClass,则最终会调用foo_worker(SomeClass*)
  • 如果KSomeOtherClass,则会调用foo_worker(SomeOtherClass*)
  • 否则将调用通用foo_worker

注意foo_worker中的参数用于使编译器能够选择正确的重载函数。

答案 4 :(得分:-1)

问题通常是模板类的特殊化,需要专门化整个类,如果类具有大的接口则不方便。一种方法是提供另一个间接级别,如下所示:

#include <iostream>

template<int T>
class MyClass {
public:
    MyClass(){};
    ~MyClass(){};

    class fooImpl;

    template<class K> void foo()
    {
       fooImpl::fn<K>();
    }
};

template<>
class MyClass<2>::fooImpl
{
public:
   template <class K> static void fn()
   {
      std::cout << "two : " << typeid(K).name() << "\n";
   }
};

template<>
class MyClass<3>::fooImpl
{
public:
   template <class K> static void fn()
   {
      std::cout << "three : " << typeid(K).name() << "\n";
   }
};

class SomeClass {};
class SomeOtherClass {};

int main()
{
   MyClass<2> myc2;
   MyClass<3> myc3;
   myc2.foo<SomeClass>();
   myc2.foo<SomeOtherClass>();
   myc3.foo<SomeClass>();
   myc3.foo<SomeOtherClass>();

   return 0;
}

然后你只需要专门化foo(fooImpl)的实现类,而不是你想要添加的MyClass上的所有其他成员函数。

我的编译器提供了以下输出:

two : class SomeClass
two : class SomeOtherClass
three : class SomeClass
three : class SomeOtherClass