我正在使用Allegro创建一个简单的游戏。当我尝试验证我的显示指针不为null时,我收到编译器错误告诉我
错误C2664:' void 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;
}
如果我通过验证&#34;!display&#34;而不是&#34;显示&#34;有用。我意识到我可以使用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
答案 0 :(得分:10)
std::unique_ptr
不能隐式转换为bool。它在上下文中可以转换为bool(由于它的explicit conversion operator),这就是为什么你可以在if语句中使用它,或者在它前面放一个!
,但你不能将它作为参数传递一个期待一个布尔的功能。
答案 1 :(得分:1)
最好的想法是使用宏进行此类验证。有几个原因:
1)因为您可以(并且应该)在没有_DEBUG(发布版本)的情况下构建时删除验证代码,因此:
#if _DEBUG
# define VALIDATE(test, msg) validate(!!(test), msg)
#else
# define VALIDATE(test, msg)
#endif // _DEBUG
多亏了这样的方法,你有相同的代码使用验证,但是当你构建Release时,由于使用了验证,你没有性能损失(通常当你在调试中获得一个断言时,你也会在发布版本中获得相同的断言)
2)您可以使用我在上面的代码示例中使用的内容:
!!(test)
迫使布尔施放。现在你可以写:
std::unique_ptr ptr{...};
VALIDATE(ptr, "FAIL: Wrong ptr!");