2011-03-18 62 views
1

如何將變量區分爲編譯器構造的字符串?C++ 11 - 區分右值指針

例如,而右值"Hello, World"的類型爲const char*const char*本身並不意味着指針不能被改變。一個char* const指針不能改變,但這不是編譯器構造的。

這是否意味着,對於任何包含const char*的容器,數據應該通過C++的移動語義以外的方式複製?有沒有什麼辦法可以移動編譯器構造的字符串,並讓所有其他字符串獨立?

例如,在GCC 4.5.2中,返回類型int而不是int&的方法被視爲返回int&&。我不知道實際的標準是否應該是這樣,但這就是GCC目前所做的。

編輯:爲了澄清,我的意思是應該複製指針指向的實際內存。這意味着必須分配新的內存,並且指針中的數據應該被複制到新的位置。

+0

我不太瞭解「編輯」。你能澄清嗎? – 2011-03-18 00:55:53

回答

8

"Hello, World"不是類型const char*。它是const char[13]的類型,它是一個左值,而不是右值。

當在其被隱式轉換爲const char*指向到其初始元素的上下文使用"Hello, World",所得到的指針是一個rvalue(因爲它是從隱式轉換得到的臨時對象。

例如,在GCC 4.5.2,返回類型int而非int&被視爲返回int&&的方法。

如果調用由值返回的函數(例如。,int),那麼該函數調用表達式是一個右值表達式。如果您調用返回左值引用的函數(例如,int&),那麼該函數調用表達式是一個左值表達式。

如何區分一個變量作爲編譯器構造的字符串?

你不能,真的:"Hello, World"和你可能聲明的任何其他const char[13]沒有區別。

至於在標準庫容器如std::vector中存儲const char*或任何其他指針類型,容器不會觸及指向的數據:容器正在創建,移動,複製和銷燬指針。

如果您需要管理指向數據,您需要通過編寫一個類來管理指向的對象(非常類似智能指針類)。編寫一個類來管理這種資源的習慣用語稱爲「資源獲取初始化」(RAII)或「範圍綁定資源管理」(SBRM)。

+0

感謝您的幫助! – 2011-03-18 00:54:04

+1

Stramge:gcc 4.5爲'f(「abcd」)'和'f(ac)'打印「rvalue const char *」。 – GManNickG 2011-03-18 01:18:50

+0

@GMan:這很有趣:它獲得了「f(a)」的權利,儘管這很奇怪。 Visual C++ 2010 SP1爲'f(new char)'輸出「'lvalue char *',這顯然是錯誤的。它還爲所有三個左值數組調用打印'lvalue char const *',並拒絕編譯兩個右值數組調用,結果顯示來自Clang 3.0(Trunk 127530),根據最新的C++ 0x草案,我認爲它們是正確的;但我會深入研究它的,儘管如此 – 2011-03-18 01:22:28

0

這是否意味着,對於任何包含const char *的容器,數據應該通過除C++的移動語義之外的方式複製?

這意味着指針被複制。沒有更多,沒有更多。指針必須複製才能使容器正常工作。