Error when implicitly pushing from std: unique_ptr for bool
I am using Allegro to create a simple game. When I try to check that my display pointer is not null, I get a compiler error telling me
error C2664: 'void validate (bool, std :: string)': cannot convert argument 1 from 'std :: unique_ptr <ALLEGRO_DISPLAY, main :: <lambda_996846ce92067e506da99cad36e610cf ->' to 'bool'
Here is my code
#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;
}
If I pass the test "! Display" instead of "display" it works. I understand that I can call validate with display.get (), but I wanted to know why it doesn't work when I pass in a smart pointer.
I found this bug report. I am using Visual Studio 2013. https://connect.microsoft.com/VisualStudio/feedbackdetail/view/775810/c-11-std-unique-ptr-cast-to-bool-fails-with-deleter-lambda
source to share
The best idea is to use a macro for this kind of check. There are several reasons:
1) because you can (and you should) remove the validation code on build without _DEBUG (build release), so:
#if _DEBUG
# define VALIDATE(test, msg) validate(!!(test), msg)
#else
# define VALIDATE(test, msg)
#endif // _DEBUG
with this approach, you have the same code that uses validations, but when you build a Release, you have no performance loss due to the use of validations (usually when you get the assert debug, you also get the same assertion in the release build)
2) you can use what I used in the example code above:
!!(test)
which makes the bool cast. Now you can write:
std::unique_ptr ptr{...};
VALIDATE(ptr, "FAIL: Wrong ptr!");
source to share