1

如果我刪除模板專門化部分(試圖打印「測試2」),代碼編譯罰款,但我希望能夠有一個特殊情況,它運行的代碼路徑對於外部用戶來說看起來很乾淨。C++模板專業化:編譯錯誤:「不是一個類型」

#include <iostream> 

using namespace std; 

struct SpecialType {}; 

template<typename A , typename B = SpecialType> 
class Test 
{ 
public: 
    class TestInner 
    { 
    public: 
     TestInner& operator*(); 
    }; 
}; 

template<typename A , typename B> 
typename Test<A , B>::TestInner& Test<A , B>::TestInner::operator*() 
{ 
    cout << "Test 1" << endl; 
    return *this; 
} 

// If the following is removed, everything compiles/works, but I want this alternate code path: 
template<typename A> 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
{ 
    cout << "Test 2" << endl; 
    return *this; 
} 

int main() 
{ 
    Test<int , SpecialType>::TestInner test; 
    *test; 

    return 0; 
} 

我在做什麼錯?

編輯: 順便說一句,編譯器錯誤讀取:

main.cpp:26:44: error: 'Test<A, SpecialType>::TestInner' is not a type 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
              ^
main.cpp:26:89: error: invalid use of dependent type 'typename Test<A, SpecialType>::TestInner' 
typename Test<A , SpecialType>::TestInner& Test<A , SpecialType>::TestInner::operator*() 
                         ^

回答

7

添加一個聲明爲專業類:

template<typename A> 
class Test<A, SpecialType> 
{ 
public: 
    class TestInner 
    { 
    public: 
     TestInner& operator*(); 
    }; 
}; 

的問題是,你定義一個成員的專業化是沒有聲明。模板化類的專業化不會與通用化模板共享任何成員或方法,因此通用化模板的聲明不能作爲該模板類的任何專業化的聲明。

考慮一下:

template <class T> 
class Foo { 
    void GeneralFunction(T x); 
} 

和專業化:

template <> 
class Foo<int> { 
    void SpecialisedFunction(int x); 
} 

這裏,Foo</*anything except int*/>只有方法GeneralFunctionFoo<int>只有方法SpecialisedFunction

通過同樣的邏輯,這也是允許的:你需要聲明你的專業化

template<> 
class Foo<float> { 
    float GeneralFunction; //here GeneralFunction is a data member, not a method. 
} 

長話短說。

+0

謝謝。快速後續問題:如果Test Test 具有其他功能,是否有任何干淨的方式可以將其餘的功能繼承到Test 中,但只專注於該功能?我試圖避免大規模代碼重複。 – Jonathan

+0

@Jonathan據我所知,不僅僅使用模板專業化。你也許可以通過混合繼承來實現某些東西。 – bolov

+0

@Jonathan做了一點研究:你想要的是使用'好奇的循環模板模式'。見http://stackoverflow.com/questions/6220337/code-duplication-and-template-specialization-when-the-specialized-function-has http://stackoverflow.com/questions/2757816/class-template-specializations-與共享功能 – bolov