2012-09-25 41 views
3

我將一個項目從MSVC移植到Borland C++,我遇到了困難template functions。例如,下面的模板功能實例化的可移植性問題

void fn(const char *buffer) 
{ 
    vector<string> output; 
    boost::split(output, string(buffer), is_any_of(",")); 
    // ... 

導致編譯器錯誤:

[BCC32 Error] example.cpp(208): E2285 Could not find a match for 'split<SequenceSequenceT,RangeT,PredicateT>(vector<string,allocator<string> >,string,is_any_ofF<char>)' 

而變形例

void fn(const char *buffer) 
{ 
    vector<string> output; 
    string sBuffer(buffer); 
    boost::split(output, sBuffer, is_any_of(",")); 
    // ... 

編譯罰款。

如帖子標題所示,此問題的泛化是,在某些情況下,如果將參數作爲在函數的參數列表內構建的臨時對象傳入,BCC似乎不匹配模板函數。

在更改所有受影響的代碼之前,我想了解爲什麼BCC認爲第一個示例是錯誤的。這是編譯器的缺陷,還是我的代碼不符合C++標準?我正在使用RAD Studio/C++ Builder XE2

+4

「我正在將一個項目從MSVC移植到Borland C++」哦,我可憐你必須承受的地獄。 –

+0

「我正在將一個項目從MSVC移植到Borland C++」我此刻停止閱讀。 –

+2

'boost :: split'是否通過引用,'const'引用或值來引用參數?如果第一個錯誤是正確的,因爲你不能將一個非''const'引用綁定到一個臨時對象。 –

回答

3

這不是因爲該函數是一個模板;這是因爲由於某種原因,它需要它的Input參數作爲非const左值參考,作爲記載here

template<typename SequenceSequenceT, typename RangeT, typename PredicateT> 
    SequenceSequenceT & 
    split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred, 
     token_compress_mode_type eCompress = token_compress_off); 

在標準C++,你不能臨時右值,例如綁定爲string(buffer),到這樣的參考。在微軟對語言的想象力重新解讀中,你可以。

解決方案就是完成你所做的事情:引入一個可以通過引用傳遞的命名的非臨時變量。

3

從提升手動

template<typename SequenceSequenceT, typename RangeT, typename PredicateT> 
    SequenceSequenceT & 
    split(SequenceSequenceT & Result, RangeT & Input, PredicateT Pred, 
     token_compress_mode_type eCompress = token_compress_off); 

這似乎是功能確實通過引用採取它的參數,所以你的「解決辦法」,實際上是使用它的正確途徑。

已知MSVC允許綁定到非const引用作爲「擴展名」。