2014-02-10 61 views
1

我隔壁班的C++ CLI:C++ CLI:cliext :: vector <T>作爲公共類函數的返回類型?

public ref class MyClass 
    { 
     public: 
      MyClass(void); 
      virtual bool Init(); 

      cliext::vector<int>^ ListOfNumbers(); 
    }; 

我想從公共溫控功能recive INT的載體。

這裏是IMPL:

cliext::vector<int>^ MyClass::ListOfNumbers() 
{ 
    cliext::vector<int>^ devs = gcnew cliext::vector<int>(); 
    devs->push_back(1); 
    return devs; 
} 

我的問題是,我得到了下一個警告:

警告C4677: 'ListOfNumbers':非私有成員 包含裝配專用型「cliext的簽名:: vector < _Value_t>'

有人能告訴我原因嗎?我可以從公共函數C++ CLI類收到項目嗎?

+1

似乎我應該使用從系統名單,不要問這樣的愚蠢的問題...... =) – user2706838

+1

使用STL/CLR永遠不會[錯誤](http://www.codeproject.com/Articles/24206)/A-查找在-STL-CLR-性能換線性容器)。是的,請使用'List '。 –

回答

3

實際上,我不知道它,但如果所有CLI 模板實例化都是私有的,並且不能通過公共組裝接口公開,那麼我不會感到驚訝。您知道,與其他.Net程序集交談時,由C++/CLI生成的模板並不真正有用,而「與其他.NET交談」正是C++/CLI的用途。

如果(我可以這樣稱呼它們)「Native C++模板」只能從C++端使用和訪問只有。由於編譯器的C++部分無法爲這些CLR運行時生成正確的類型描述,CLR運行時通常無法對它們進行操作。 (*)

要創建.Net接口,請使用.Net BCL類型。使用泛型而不是模板。所以,看看像System.Collections.Generic.List<>這樣的類型。他們可以安全地暴露在公共界面中。 (**)

請記住,C++/CLI是原生C++和.Net的混合物。您可以輕鬆訪問這兩個世界,但這些世界並不喜歡被混合;)

編輯: (*)正如JochenKalmbach提醒的那樣,它適用於「本地」模板。微軟已經準備了一個特殊的STL版本,實現了一些的核心收集接口,因此其vector實際上實現了System.Collection.Generic.IEnumerable。這vector這裏仍然受到本機限制,不能直接發佈通過asembly接口本身(如vector<>)。但是,後一種類型(IEnumerable)是完全正常的CLR類型,可以暴露。所以,例如:

System::Collections:::Generic::ICollection<int>^ MyClass::ListOfNumbers() 
{ 
    cliext::vector<int>^ devs = gcnew cliext::vector<int>(); 
    devs->push_back(1); 
    return devs; 
} 

它可能會編譯 - 但我沒有檢查。

+0

「CLR運行時無法對它們進行操作」:這是不對。正如你所看到的,「cliext :: vector」派生自ICollection和IEnumerable!因此:NET可以直接使用這個類。唯一的一點是它不能直接用於裝配邊界;但你可以將它轉換爲.NET接口,然後它就可以工作! –

+0

@JochenKalmbach這是一個很好的觀點。然而,這不是一回事:其他.NET程序集可以與這些類的*實例一起工作,只要他們不需要知道這些類本身。但它確實打開了解決問題的另一種方法:將函數聲明爲返回其中一個接口,而不是具體類型。 – hvd

+0

這是真的,我會在一分鐘內糾正措辭。我的意思是CLR運行時不能在**典型的**模板上運行,比如標準std,boost或手動製作的模板。由Microsoft庫提供的模板經過精心定製以實現橋接接口。但這只是一個聰明的竅門,在一般用法中不可能。 – quetzalcoatl

0

是的,你可以返回集合。檢查此鏈接

http://msdn.microsoft.com/en-us/library/bb385659.aspx

但如果你想使用.NET Framework或本機C這種方法++你有這個集合轉換爲特定語言的兼容集合。

+0

警告不能被忽略。如果你看看你的鏈接,你必須聲明cliext類型爲「private」(然後警告消失),並返回相應的.NET泛型類型... –

2

cliext :: vector不適用於裝配邊界。它只能在你的C++/CLI項目中使用。因此添加一個「private:」並在公共接口中返回一個「IEnumerable」。