2015-05-29 129 views
3

我正在使用Allegro創建一個簡單的遊戲。當我嘗試驗證我的指針顯示不爲空,我得到一個編譯器錯誤,告訴我將std:unique_ptr隱式強制轉換爲bool時出錯

錯誤C2664:「無效的validate(BOOL,的std :: string)」:不能轉換 參數1從'的std ::的unique_ptr < ALLEGRO_DISPLAY,主要:: < lambda_996846ce92067e506da99cad36e610cf >>」到 '布爾'

這裏是我的代碼

#include <iostream> 
#include <memory> 
#include <string> 

#include <allegro5\allegro.h> 

using namespace std; 

const int WIDTH = 512; 
const int HEIGHT = 512; 

void validate(bool ptr, string errorMessage) { 
    if (!ptr) { 
     cerr << errorMessage << endl; 
     exit(-1); 
    } 
} 

int main() { 
    auto deleter = [](ALLEGRO_DISPLAY* d) { al_destroy_display(d); }; 
    unique_ptr<ALLEGRO_DISPLAY, decltype(deleter)> display; 

    validate(al_init(), "Failed to initialize Allegro"); 
    display = unique_ptr<ALLEGRO_DISPLAY, decltype(deleter)>(al_create_display(WIDTH, HEIGHT), deleter); 
    validate(display, "Failed to create display"); 

    return 0; 
} 

如果我通過驗證「!display」而不是「display」它的工作原理。我意識到我可以用display.get()調用validate,但是我想知道爲什麼當我傳遞一個智能指針時它不工作。

我發現了這個錯誤報告。我正在使用Visual Studio 2013. https://connect.microsoft.com/VisualStudio/feedbackdetail/view/775810/c-11-std-unique-ptr-cast-to-bool-fails-with-deleter-lambda

回答

9

std::unique_ptr不能隱式轉換爲bool。它可以上下文轉換爲bool(由於它的explicit conversion operator),這就是爲什麼你可以在if語句中使用它,或者在它前面放置一個!,但是你不能將它作爲參數傳遞給期望bool的函數。

1

最好的想法是使用宏來進行驗證。有幾個原因:

1),因爲你可以(而且當你建立一個沒有_DEBUG(發佈版本,你應該)刪除驗證碼),所以:

#if _DEBUG 
# define VALIDATE(test, msg) validate(!!(test), msg) 
#else 
# define VALIDATE(test, msg) 
#endif // _DEBUG 

鑑於這樣的方式你有相同的代碼是使用驗證,但是當你建立發佈你沒有性能損失,因爲使用驗證(通常當你在調試中得到一個斷言,你也會在發佈版本中得到相同的斷言)

2)你可以使用我已經用於上面的代碼示例中:

!!(test) 

哪個力量布爾演員。現在,你可以寫:

std::unique_ptr ptr{...}; 
VALIDATE(ptr, "FAIL: Wrong ptr!");