从Visual Studio 2010迁移到2012时出现C++ 11问题

Mat*_*ine 7 c++ unique-ptr visual-c++ c++11 visual-studio-2012

我正在尝试将我的项目从Visual Studio 2010移植到Visual Studio 2012.在我的代码中,我有一些文件处理,如下所示:

auto fileDeleter = [](FILE* f) { fclose(f); };

unique_ptr<FILE, decltype(fileDeleter)> fMinute(
    fopen(minuteLogName.c_str(), "w"), fileDeleter);


unique_ptr<FILE, decltype(fileDeleter)> fIndividual(
    fopen(individualLogName.c_str(), "w"), fileDeleter);

if (!fMinute || !fIndividual) {
    throw Exceptions::IOException("One of the log files failed to open",
                                  __FUNCTION__);
}
Run Code Online (Sandbox Code Playgroud)

这在2010年没有任何问题,但在2012年它失败了条件:

错误C2678:二进制'!' :没有找到哪个运算符采用类型>'std :: unique_ptr <_Ty,_Dx>'的左手操作数(或者没有可接受的转换)
...
可能是'内置C++运算符!(bool)'

C++ 11标准指定unique_ptr有一个bool运算符,允许你像我上面那样进行快速检查.更奇怪的是,VS2012的unique_ptr定义有这样的运算符:

_OPERATOR_BOOL() const _NOEXCEPT
{   // test for non-null pointer
    return (this->_Myptr != pointer() ? _CONVERTIBLE_TO_TRUE : 0);
}
Run Code Online (Sandbox Code Playgroud)

但是我在编译时遇到了这个错误.为什么?

是的,我可以只是使用ofstream,但这是重点.

Nic*_*las 6

在BigBoss所说的基础上,C++ 11需要std::unique_ptr使用explicit operator bool() noexcept,这解决了整个隐式转换为bool问题.除了...... VC2012还不支持 explicit运营商.因此,他们必须使用安全布尔的习语.

虽然安全布尔成语很好,但它可能有缺陷(这就是为什么explicit operator bool()存在),这取决于你如何实现成语.你显然在VC2012遇到过其中一个.重新配置您的测试,!(fMinute && fIndividual)应该解决它.

但无论哪种方式,它都是Visual Studio的错误.由于行为发生了变化,即使您设法找到解决方法,也应该提交错误报告.