使用三元运算符“移动或抛出”

时间:2019-07-02 07:38:06

标签: c++ c++11 gcc

自C ++ 11起,我一直在根据某些条件使用三元运算符进行移动或抛出,但是使用最新的GCC(9.1和主干)后,它不再起作用。

我已将问题简化为此示例(Wandbox permalink):

JP

它适用于GCC 8.3及更早版本以及每个Clang版本;并且[{ 'code': 'INVALID_PARAMETER', 'message': 'Expected GeoId, got "JP" for country', 'parameter': 'country' }]> 被移动了:

#include <iostream>
#include <memory>

int main() 
{
    auto p = std::make_unique<int>();
    std::cout << "p.get(): " << p.get() << std::endl;

    {
        std::cout << "Move p into q" << std::endl;
        auto q = p ? std::move(p) : throw std::invalid_argument{"null ptr"};

        std::cout << "q.get(): " << q.get() << std::endl;
    }

    std::cout << "p.get(): " << p.get() << std::endl;
    return 0;
}

但是现在在GCC 9.1和更高版本中它不起作用:

p

然后该程序由于两次释放而崩溃。

这是GCC 9.1 / trunk中的错误吗?还是最新的GCC是唯一做正确的事,这不是有效的C ++吗?

1 个答案:

答案 0 :(得分:3)

已经是一个错误。

由于尝试复制unique_ptr(或者发生throw都没有关系),要么是移动就是移动,否则编译将失败。

q.get() == p.get()实际上表明内部结构已损坏,因为这不可能。

我同意cpplearner的说法,这是bug 90393(及其所有重复),据报道是在GCC 9.1中引入的。

要么降级,要么等待升级,要么将代码重构为漂亮的if / else。 ?