2014-11-26 28 views
5

Minimal Code, um das Problem reproduzieren:Warum verwendet der Compiler eine temporäre Variable?

#include "stdafx.h" 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
    CComBSTR ccbTest(L"foo"); 
    const wchar_t * pTest = ccbTest ? ccbTest : L"null string"; 

    return 0; 
} 

Der Compiler verwendet eine temporäre CComBSTR, wenn es einen Zeiger in pTest speichern möchte. Es verwendet dann die BSTR Konvertierung, die in der CCcomBSTR Klasse mit dem temporären verfügbar ist, und speichert den Zeiger in pTest. Dann wird das temporäre zerstört, und ich bin mit einem baumelnden Zeiger in pTest verlassen.

Das Update ist die CComBSTR würfen

const wchar_t * pTest = ccbTest ? static_cast<BSTR>(ccbTest) : L"null string"; 

Ich verstehe nicht, warum das Update erforderlich ist. Ich dachte, dass der Compiler nur versuchen würde, selbst zu BSTR zu konvertieren. Warum ein temporäres?

Antwort

2

Das temporäre existieren aus den gleichen Gründen this question tut.

Und wie in one of its answer erklärte:

Die Art des ternären: Ausdrucks ist die häufigste Art von seinem zweiten und dritten Argumente. Wenn beide Typen gleich sind, erhalten Sie eine Referenz zurück. Wenn sie ineinander konvertierbar sind, wird man ausgewählt und die andere wird konvertiert [...]. Da Sie keine Lvalue-Referenz auf eine temporäre (die konvertierte/heraufgestufte Variable ) zurückgeben können, ist ihr Typ ein Werttyp.

Da Ihr L"null string" ist eine temporäre eines anderen Typs als CComBSTR das gesamte Ergebnis des ternären ein Werttyp ist, die das Ergebnis bedeutet, in einem temporären kopiert.

Wenn Sie versuchen:

CComBSTR ccbTest(L"foo"); 
CComBSTR ccbNull(L"ull string"); 

const wchar_t * pTest = ccbTest ? ccbTest : ccbNull; 

Es gibt keine mehr nur vorübergehend ist.

0

Ich sehe keine temporäre CComBSTR in Ihrem obigen Beispiel.

CComBSTR ist eine RAII-Wrapper-Klasse, die verwendet wird, um die Lebensdauer von BSTR zu verwalten, und wenn der Gültigkeitsbereich überschritten wird, wird der zugrunde liegende BSTR zerstört.

ccbTest ist eine automatische (Stapel-) Variable und wenn sie außerhalb des Bereichs (am Ende von _tmain) liegt, wird sie und der BSTR, den sie verwaltet, zerstört.

+0

Bitte versuchen Sie meinen Code, debuggen und treten Sie in die Anrufe: Es gibt ein temporäres, auch wenn Sie es nicht "sehen" :-) – manuell