2015-05-29 126 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!");