从std:unique_ptr到bool的隐式强制转换出错

时间:2015-05-29 05:36:16

标签: c++ c++11 visual-studio-2013 smart-pointers allegro

我正在使用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

2 个答案:

答案 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!");