[英]C++ Does it make sense to declare a template function with static inline?
[英]Does this C++ static analysis rule make sense as is?
我正在實現一些C ++靜態分析規則,其中一個規則禁止函數返回引用或指向函數引用參數的指針,即以下都是不兼容的:
int *f(int& x) { return &x; } // #1
const int *g(const int& x) { return &x; } // #2
int& h(int& x) { return x; } // #3
const int& m(const int& x) { return x; } // #4
為此給出的理由是“它是實現定義的行為,無論引用參數是臨時對象還是對參數的引用”。
然而,我對此感到困惑,因為C ++中的流操作符是以這種方式編寫的,例如
std::ostream& operator<<(std::ostream& os, const X& x) {
//...
return os;
}
我認為我非常有信心C ++中的流操作符通常不會表現出實現定義的行為,所以發生了什么?
根據我目前的理解,我希望#1和#3能夠很好地定義,因為temporaries不能綁定到非const引用,所以int& x
指的是一個超出生命周期的真實對象函數的范圍,因此返回指向該對象的指針或引用是好的。 我希望#2是狡猾的,因為臨時可能已經綁定到const int& x
,在這種情況下嘗試獲取其地址似乎是一個糟糕的計划。 我不確定#4 - 我的直覺是,這也可能是狡猾的,但我不確定。 特別是,我不清楚以下情況會發生什么:
const int& m(const int& x) { return x; }
//...
const int& r = m(23);
正如你所說,#1和#3都很好(雖然#1可以說是糟糕的風格)。
#4是出於同樣的原因而狡猾#2是; 它允許將const引用傳播到其生命周期的臨時值。
讓我們檢查:
#include <iostream>
struct C {
C() { std::cout << "C()\n"; }
~C() { std::cout << "~C()\n"; }
C(const C &) { std::cout << "C(const C &)\n"; }
};
const C &foo(const C &c) { return c; }
int main() {
const C &c = foo(C());
std::cout << "c in scope\n";
}
這輸出:
C()
~C()
c in scope
在C ++ 11中,如果還存在右值引用過載,則可以使#2和#4安全。 從而:
const int *get( const int &x ) { return &x; }
const int *get( const int &&x ) { return nullptr; }
void test() {
const int x = 0;
const int *p1 = get( x ); // OK; p1 is &x.
const int *p2 = get( x+42 ); // OK; p2 is nullptr.
}
因此,盡管它們很狡猾,但如果程序員知道他們在做什么,它們確實有安全用途。 禁止這樣做是非常嚴厲的。
(如果const rvalue引用重載是私有的,未定義的,或者導致編譯時或鏈接時錯誤,則可能更安全。對於#4情況尤其如此,我們返回引用但沒有任何內容很好地返回引用,語言不允許引用null。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.