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

10

我正在使用 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()调用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个回答

20

std::unique_ptr不会隐式转换为bool类型。它可以通过上下文的转换(由于其显式类型转换运算符)转换为bool类型,因此您可以在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!");

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接