簡體   English   中英

如何允許將C ++ 98 API的臨時值轉換為l值

[英]How to allow conversion of temporary to l-value for C++98 API

我有C ++ 98 API,通過非const 引用獲取值並更改此值。
具體來說,我正在使用OpenCV,函數是cv::rectangle() ,它采用了cv::Mat & image。

同樣的API也使用表達式模板來優化圖像算術。 我可以通過創建表示子圖像的(非常量)臨時包裝對象在感興趣區域(ROI)上繪制一個矩形。

有了VS2010,我可以寫:

cv::Mat a(10,10,CV_8UC1); // create 10x10 image
Rect rec(0,0,2,2);        // create 2x2 rectangle
cv::rectangle(a, rec, cv::Scalar::all(0));      // (1) draw 2x2 on full image
cv::rectangle(a(rec), rec, cv::Scalar::all(0)); // (2) draw 2x2 on 2x2 sub-image << !!!

這沒有問題。 在第(2)行,創建一個臨時子圖像包裝器對象,並通過引用傳遞給cv::rectangle

但是,在支持C ++ 11的 Clang的XCode for iOS上,第(2)行會出現以下錯誤:

.../test.cpp:605:5: No matching function for call to 'rectangle'
.../core.hpp:2594:17: Candidate function not viable: expects an l-value for 1st argument 

為了完整起見,這是相關的原型:

//! draws the rectangle outline or a solid rectangle covering rec in the image
CV_EXPORTS void rectangle(CV_IN_OUT Mat& img, Rect rec,
                          const Scalar& color, int thickness=1,
                          int lineType=8, int shift=0);

我認為這是因為a(rec)創建了一個臨時的,它被ref傳遞給cv::rectangle ,並且編譯器不允許將此臨時轉換為l值。 也許這個臨時自動定義為const?
我確實傳遞了一個臨時的,但臨時是一個實際的非const l值的包裝器,應該允許自由更改。

有沒有辦法告訴Clang放松這些限制?
是否有可能告訴編譯器這些頭文件來自C ++ 98庫,因此應該像C ++ 98一樣處理臨時文件? 類似於做extern "C"
有沒有辦法允許將臨時值轉換為l值。

當然,我可以編寫auto b=a(rec)並傳遞b代替,但是用一堆命名的臨時代碼填充代碼並擊敗包裝類的目的。

回答自己...經過一些研究后,似乎這種行為是由標准決定的,VS2010在這里是不符合要求的。
此行為旨在防止意外錯誤,但我的用例實際上是標准禁止的有效用例的示例。

規則: 非const臨時值綁定到 const引用。
const臨時的區別在於,你可以在臨時上調用非const方法。
如果這樣的方法返回,例如*this ,則結果l值 ,因此將綁定到非const引用。

有關詳細信息,請參閱此處此處

正如上面的@Xeo評論,在C ++ 11中,也可以編寫從r值l值的轉換器: template<class T> T& as_lvalue(T&& v){ return v; } // add 'hazard' icon template<class T> T& as_lvalue(T&& v){ return v; } // add 'hazard' icon
但是,應該特別小心使用(或根本不使用)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM