2016-12-28 109 views
0

我嘗試寫一些函數模板在這樣的一個C++/CLI命名空間:函數模板++/CLI

// header file 
namespace MyCLI { 
    namespace MyFunctions { 
     template <typename T> 
     double sum(T a, T b) { 
      return (double) a + b; 
     } 
    } 
} 

的第一個問題是,當我編譯該項目爲一個dll,並嘗試要使用它,名稱空間MyFunctions不會顯示出來。我認爲,正在發生的事情,因爲我還沒有明確的實例化我的模板,我需要的所有類型,所以我添加下面的頭文件的底部:

extern template double MyCLI::MyFunctions::sum<double>(double,double); 

但是,這仍然不給我訪問功能sumdouble類型。我懷疑是因爲項目被編譯成託管代碼,這是遵循C#的規則,你不能沒有類沒有功能。所以下次我試圖做一個類的命名空間MyCLI內,使sum類的這樣的靜態成員:

// header file 
namespace MyCLI { 

    public ref class MyFunctions 
    { 
    public: 
     template <typename T> 
     static double sum(T a, T b) { 
      return (double) a + b; 
     } 
    }; 
} 

extern template double MyCLI::MyFunctions::sum<double>(double,double); 

現在,當我使用匯編我可以看到在MyCLIMyFunctions類,但我仍然無法訪問該類的sum函數。

如果有人能給我任何關於如何解決這個問題的指示,或者我爲什麼首先面對這個問題,我將非常感激。

回答

3

這不是顯式實例化模板的正確語法。您需要刪除extern關鍵字並將實例化放在一個cpp文件中(而不是頭文件),因此只定義一次。您無法看到該方法,因爲由於缺少模板實例化而不存在。模板是而不是泛型,它們看起來很相似但有很大的不同。在編譯時實例化,而泛型在運行時實現

但是,如果你打算使用此代碼從你的運氣了不同的.NET語言:該方法將字面上包含尖括號中的名字,所以你會使用它沒有打破也很難該語言的命名規則。你可以使用反射,但我相信這不是你想要的。

對於這種簡單的情況,您可以簡單地寫幾個重載(根本不使用模板),這是最簡單的事情。如果你想要更多花哨的東西,請參閱my answer here獲取靈感。