2012-02-24 154 views
2

我有一個類結構是模板模板的會員專業化

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

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

現在我要專注基於在MyClass<int>使用的整數值的foo()方法,例如,如果INT代碼,我們有MyClass<2>如果我有MyClass<3>,我想要使用不同版本的foo<K>()。不過我想在K上仍然有foo<K>()未專門化。

因此,這將意味着這樣的事情會好起來的

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

是否有可能專門以這種方式而不是專注於K?我嘗試了幾個組合,但沒有成功。

回答

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> 
} 
+0

你好jrok,你似乎已經釘牢了我想要的東西,不幸的是我嘗試了你已經建議的東西,它給出錯誤「C2244」 - 「無法將函數定義匹配到現有的聲明」。 – Dan 2012-02-24 15:52:52

+0

@丹我使用GCC。我不是模板專家,所以我不確定哪種編譯器在這種情況下是正確的。 – jrok 2012-02-24 15:53:50

+0

它對GCC有效嗎?它似乎應該爲我工作,但我使用VS2010,它不喜歡它。不幸的是,其他代碼依賴於VS2010,所以我可能需要解決。 – Dan 2012-02-24 16:01:49

-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中的參數用於使編譯器能夠選擇正確的重載函數。

+0

這是否幫助我專注於'T '只有?如果是這樣,我不能立即看到如何。 – Dan 2012-02-24 15:46:54

+0

@丹:這是什麼意思?我沒有得到你。 – Nawaz 2012-02-24 15:48:31

+0

好吧,說我有兩個函數'foo '和'bar ',它們都使用一些泛型類型'K',但功能不同。現在我想給他們兩個相同的名字,並根據值「T」選擇要調用哪一個(但仍然可以使用任何「K」)。 – Dan 2012-02-24 16:00:46

1

您可以嘗試提高:: enable_if,它允許啓用或禁用的類和方法的具體專業。看看這裏的例子:http://www.boost.org/doc/libs/1_48_0/libs/utility/enable_if.html

+0

是的,它是有用的,但只在SFINAE有意義的地方,這需要它在功能參數。並不總是很容易使用。 – 2013-11-15 09:54:38

-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; 
} 

那麼你就只能有專攻富(fooImpl)的實現類,而不是所有的MyClass的其他成員函數,你可能需要添加。

我的編譯器提供了以下的輸出:

two : class SomeClass 
two : class SomeOtherClass 
three : class SomeClass 
three : class SomeOtherClass 
+0

你可以專注於這些功能,而通過嵌入來實現你所建議的正常方式。 – 2012-02-24 16:11:33

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 
+0

是的,我再次嘗試它,它的工作,我必須有別的地方別的東西。 :) – Dan 2012-02-24 16:19:22