2014-06-24 31 views
0

我有具有2個參數的基類模板,T是子類,標誌意味着我想激活一些功能,默認爲假:爲什麼dllexport編譯不是專門的模板成員函數?

template 
< 
    typename T, 
    bool flag 
> 
class SomeBase 
{ 
public: 
    static Info& GetInfo() 
    { 
     static Info& instance = CreateInfo<T>(T::ClassName()); 
     static bool inited = false; 
     if (!inited) 
     { 
      Test<flag>(instance); 
      inited = true; 
     } 
     return instance; 
    } 

private: 
    template<bool enable> 
    static void Test(Info& instance) 
    { 
     return; 
    } 
    template<> 
    static void Test<true>(Info& instance) 
    { 
     T::Add(fields); 
    } 
}; 

和使用該基:

class /*dllexport*/ MyClass : public SomeBase<MyClass, false> 
{ 
public: 
    // ... 
}; 

flag模板參數設置爲false,所以根據我的專業化,它應該編譯上面的空函數,編譯器會這樣做,這很好。

但是,如果我添加dllexportMyClass,那麼編譯器是給C2039,它說'Add' is not a member of MyClass,這沒有道理,因爲我使用SomeBaseflag == false

爲什麼加入dllexport,使編譯器嘗試編譯錯誤的專業化?

////////////////////////////////////////
編輯1:
////////////////////////////////////////
根據此鏈接:

http://msdn.microsoft.com/en-us/library/twa2aw10%28v=vs.100%29.aspx

在談論SomeBase<MyClass, false>聲明when one or more of the base classes is a specialization of a class template

如果是這樣,the compiler implicitly applies dllexport to the specializations of class templates表示編譯器正在將dllexport添加到SomeBase<MyClass, false>

而且,由於我已經完全專用static void Test(Info& instance),因此編譯器應該選擇正確版本Test(),即Test<false>()

那麼怎麼來的是選擇(或編譯)錯誤的版本(Test<true>())?

謝謝!

+0

我認爲有DLLEXPORT上一個模板類驗證沒有太大的意義。無論如何,您需要在使用時提供完整的頭文件。編譯器可能會嘗試爲鏈接器創建類的完整定義,但這種方法不起作用。 – PMF

+1

嗨,我是'myLlass'' MyClass',而不是'SomeBase'。 'MyClass'不是類模板,對嗎? –

回答

0

沒有DLLEXPORT,你會當你從主調用MyClass的::的GetInfo得到同樣的錯誤。 在這種情況下,編譯器正在擴展並僅編譯部分被調用的代碼。 但隨着dllexport,它擴展和編譯的一切。

你可以用這個

template <typename T> 
class SomeBase 
{ 
public: 
    void test() 
    { 
     dafsaf; 
    } 
private: 
}; 

class /*__declspec(dllexport)*/ MyClass : public SomeBase<MyClass> 
{ 
public: 
    // ... 
}; 

int main() 
{ 
    MyClass o; 
    //o.test(); 
    return 1; 
} 
+0

沒有dllexport我沒有錯誤:/你說「它擴展和編譯一切」,是否有任何提及這種行爲?謝謝! –

+0

你可以參考這個鏈接http://msdn.microsoft.com/en-us/library/twa2aw10%28v=vs.100%29.aspx,搜索和解讀「編譯器隱式地將dllexport應用於類的特化模板「 – PankajM

+0

嗨,我讀過這個,但我不太清楚它的含義。語句「當一個或多個基類是類模板的專業化」時,會討論'SomeBase '?如果是這樣,'編譯器將dllexport隱式應用於類模板的特化「意味着編譯器將'dllexport'添加到'SomeBase ',並且,因爲我已經完全專門化了'static void Test(Info&instance ),編譯器應該選擇正確版本的Test()。那麼它如何選擇(或編譯)錯誤的版本? –