我有一個函數,我希望編譯器始終使用NRVO ......即使在調試模式下。這是否有一個附註?如何在msvc中強制返回值優化
這裏是我的類,它工作在「釋放」模式極大:
template <int _cbStack> class CBuffer {
public:
CBuffer(int cb) : m_p(0) {
m_p = (cb > _cbStack) ? (char*)malloc(cb) : m_pBuf;
}
template <typename T> operator T() const {
return static_cast<T>(m_p);
}
~CBuffer() {
if (m_p && m_p != m_pBuf)
free(m_p);
}
private:
char *m_p, m_pBuf[_cbStack];
};
類是用來使堆棧上的緩衝區,除非比_cbStack字節更是必需的。然後,當它破壞時,如果它分配了任何內存,它將釋放內存。當連接到需要字符串緩衝區的c函數時,它很方便,並且您不確定最大大小。
反正我是想寫可以在這個測試返回CBuffer,像函數:
#include "stdafx.h"
#include <malloc.h>
#include <string.h>
template <int _cbStack> CBuffer<_cbStack> foo()
{
// return a Buf populated with something...
unsigned long cch = 500;
CBuffer<_cbStack> Buf(cch + 1);
memset(Buf, 'a', cch);
((char*)Buf)[cch] = 0;
return Buf;
}
int _tmain(int argc, _TCHAR* argv[])
{
auto Buf = foo<256>();
return 0;
}
我指望NRVO使FOO()快。在發佈模式下,它效果很好。在調試模式下,它顯然失敗了,因爲我的類中沒有拷貝構造函數。我不想要一個拷貝構造函數,因爲開發人員會使用CBuffer來複制所有內容50次。 (Rant:這些人使用動態數組類來創建20個字符的緩衝區以傳遞給WideCharToMultiByte(),因爲他們似乎忘記了您可以在堆棧中分配一個字符數組。我不知道是否他們甚至知道堆棧是什麼......)
我真的不想編碼拷貝構造函數,所以代碼在調試模式下工作!它變得龐大而複雜:
template <int _cbStack>
class CBuffer {
public:
CBuffer(int cb) : m_p(0) { Allocate(cb); }
CBuffer(CBuffer<_cbStack> &r) {
int cb = (r.m_p == r.m_pBuf) ? _cbStack : ((int*)r.m_p)[-1];
Allocate(cb);
memcpy(m_p, r.m_p, cb);
}
CBuffer(CBuffer<_cbStack> &&r) {
if (r.m_p == r.m_pBuf) {
m_p = m_pBuf;
memcpy(m_p, r.m_p, _cbStack);
} else {
m_p = r.m_p;
r.m_p = NULL;
}
}
template <typename T> operator T() const {
return static_cast<T>(m_p);
}
~CBuffer() {
if (m_p && m_p != m_pBuf)
free((int*)m_p - 1);
}
protected:
void Allocate(int cb) {
if (cb > _cbStack) {
m_p = (char*)malloc(cb + sizeof(int));
*(int*)m_p = cb;
m_p += sizeof(int);
} else {
m_p = m_pBuf;
}
}
char *m_p, m_pBuf[_cbStack];
};
該pragma不起作用:
#pragma optimize("gf", on)
任何想法?
[對您有所幫助嗎?](http://stackoverflow.com/questions/13618506/is-it-possible-to-stdmove-objects-out-of-functions-c11/13618587#13618587) – billz
什麼?問題是你想解決這個問題的解決方案嗎? – GManNickG
爲什麼?代碼的語義不會改變。 –