从 std:unique_ptr 到 bool 的隐式转换错误
Error on implicit cast from std:unique_ptr to bool
我正在使用 Allegro 创建一个简单的游戏。当我尝试验证指向显示器的指针不为空时,我收到一个编译器错误,告诉我
error C2664: 'void validate(bool,std::string)' : cannot convert
argument 1 from 'std::unique_ptr< ALLEGRO_DISPLAY,main::<
lambda_996846ce92067e506da99cad36e610cf>>' to 'bool'
这是我的代码
#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() 调用验证,但我想知道为什么当我传递智能指针时它不起作用。
我找到了这个错误报告。我正在使用 Visual Studio 2013。
https://connect.microsoft.com/VisualStudio/feedbackdetail/view/775810/c-11-std-unique-ptr-cast-to-bool-fails-with-deleter-lambda
std::unique_ptr
不能隐式转换为 bool。它可以根据上下文转换为 bool(由于它的 explicit conversion operator),这就是为什么你可以在 if 语句中使用它,或者在它前面放一个 !
,但你不能将它作为参数传递到一个期待布尔值的函数。
最好的办法是使用宏进行此类验证。有几个原因:
1) 因为你可以(而且你应该)在没有_DEBUG(发布版本)的情况下构建时删除验证代码,所以:
#if _DEBUG
# define VALIDATE(test, msg) validate(!!(test), msg)
#else
# define VALIDATE(test, msg)
#endif // _DEBUG
感谢这种方法,您拥有使用验证的相同代码,但是当您构建 Release 时,您不会因为使用验证而导致性能损失(通常当您在调试中获得断言时,您也会在发布构建中获得相同的断言)
2) 您可以使用我在上面的代码示例中使用的内容:
!!(test)
强制 bool 转换。现在你可以写:
std::unique_ptr ptr{...};
VALIDATE(ptr, "FAIL: Wrong ptr!");
我正在使用 Allegro 创建一个简单的游戏。当我尝试验证指向显示器的指针不为空时,我收到一个编译器错误,告诉我
error C2664: 'void validate(bool,std::string)' : cannot convert argument 1 from 'std::unique_ptr< ALLEGRO_DISPLAY,main::< lambda_996846ce92067e506da99cad36e610cf>>' to 'bool'
这是我的代码
#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() 调用验证,但我想知道为什么当我传递智能指针时它不起作用。
我找到了这个错误报告。我正在使用 Visual Studio 2013。 https://connect.microsoft.com/VisualStudio/feedbackdetail/view/775810/c-11-std-unique-ptr-cast-to-bool-fails-with-deleter-lambda
std::unique_ptr
不能隐式转换为 bool。它可以根据上下文转换为 bool(由于它的 explicit conversion operator),这就是为什么你可以在 if 语句中使用它,或者在它前面放一个 !
,但你不能将它作为参数传递到一个期待布尔值的函数。
最好的办法是使用宏进行此类验证。有几个原因:
1) 因为你可以(而且你应该)在没有_DEBUG(发布版本)的情况下构建时删除验证代码,所以:
#if _DEBUG
# define VALIDATE(test, msg) validate(!!(test), msg)
#else
# define VALIDATE(test, msg)
#endif // _DEBUG
感谢这种方法,您拥有使用验证的相同代码,但是当您构建 Release 时,您不会因为使用验证而导致性能损失(通常当您在调试中获得断言时,您也会在发布构建中获得相同的断言)
2) 您可以使用我在上面的代码示例中使用的内容:
!!(test)
强制 bool 转换。现在你可以写:
std::unique_ptr ptr{...};
VALIDATE(ptr, "FAIL: Wrong ptr!");