我正在尝试将我的项目从 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__);
}
这在 2010 年构建时没有问题,但在 2012 年它失败了,条件是:
error C2678: binary '!' : no operator found which takes a left-hand operand of type > 'std::unique_ptr<_Ty,_Dx>' (or there is no acceptable conversion)
...
could be 'built-in C++ operator!(bool)'
C++11 标准规定 unique_ptr has a bool operator允许您像我上面那样进行快速检查。更奇怪的是,VS2012 的 unique_ptr 定义有这个运算符:
_OPERATOR_BOOL() const _NOEXCEPT
{ // test for non-null pointer
return (this->_Myptr != pointer() ? _CONVERTIBLE_TO_TRUE : 0);
}
但是我在编译时遇到了那个错误。为什么?
是的,我可以改用 ofstream
,但这不是重点。
最佳答案
根据 BigBoss 的说法,C++11 要求 std::unique_ptr
使用 explicit operator bool() noexcept
,这解决了整个隐式转换为 bool问题。除了... VC2012 还不支持 explicit
运算符。因此,他们必须使用 safe-bool idiom .
虽然 safe-bool 习惯用法很好,但它可能存在缺陷(这就是 explicit operator bool()
存在的原因),具体取决于您如何实现该习惯用法。你显然在 VC2012 中遇到过其中一个。使用 !(fMinute && fIndividual)
重新配置您的测试应该可以解决它。
但无论哪种方式,它都是 Visual Studio 错误。由于行为发生了变化,您应该提交错误报告,即使您设法找到解决方法也是如此。
关于从 Visual Studio 2010 迁移到 2012 时的 C++11 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12993335/