C++11移动对象时如何触发类型转换

4

我有一段简单的代码,我在GCC 5、6和8上编译了这段代码,并将其部署到一个物理测试平台上,该平台使用gcc 4.8.3进行编译。出于某种原因,在测试平台(Ubuntu 14.04)上无法编译该代码。我一直在想如何解决这个问题,但目前还没有任何进展。以下是我复制的代码:

#include <memory>
#include <utility>

struct probe_payload
{
    int id{0};
    int sub_id{0};
    int snd_ts{0};
    int rcv_ts{0};
    int rtt_ms{1000};
    double snd_bw_bps{0};
    bool end_flag{false};
};

struct probe_message
{
  public:
    using buffer_t = void const *;

    probe_payload info;
    char shim[1280];

};

template<typename Packet>
struct parcel
{
    explicit parcel(Packet&& object, int ts) : item{std::move(object)}
    {
        arrival_time = std::move(ts);
    }

    parcel() = delete;
    parcel(const parcel<Packet>& /* other */) = default;
    parcel<Packet>& operator=(const parcel<Packet>& /* other */) = default;
    parcel(parcel<Packet>&& /* other */) = default;
    parcel<Packet>& operator=(parcel<Packet>&& /* other */) = default;

    Packet item;
    int arrival_time{0};
};


template <typename T>
parcel<T> get_parcel()
{
    T a;
    return parcel<T>{std::move(a), 10};
}


int main()
{
    auto p = get_parcel<probe_message>();
    return p.arrival_time;
}

在实例化 'parcel::parcel(Packet&&, int) [with Packet = probe_message]' 时:

:48:38:需要 'parcel get_parcel() [with T = probe_message]'

:54:40:从这里开始需要

:28:67:错误:无法将 'std::move((* & object))' 从 'std::remove_reference::type {aka probe_message}' 转换为 'probe_payload'

明确的 parcel (Packet&& object, int ts) : item{std::move(object)}

我已经附上了来自 compiler explorer 的链接。


为什么你不直接写成 using buffer_t = void const *; 呢? - M.M
可能这只是gcc 4中的一个bug。 - M.M
我实际上是从另一个文件中复制的,void const * 更有意义,你是正确的。 - apramc
@M.M:我认为这是编译器的一个bug,你能想到一个解决方法吗? - apramc
2个回答

2

看起来这个GCC版本不支持花括号初始化item{std::move(object)}。但使用item(std::move(object))可以编译通过。

实时示例


2
问题的实质可以简化为:
#include <utility>

struct probe_message
{
    int id;
};

int main()
{
    probe_message a;
    probe_message b{std::move(a)};
}

这段代码被gcc 4.9.4拒绝,但被gcc 5+接受,并通过将{ }替换为( )来修复。

我认为这与List-initialization priority from object of same type中的问题相同,由DR 1467解决。

gcc 4使用该列表进行聚合初始化,无法将std::move(a)转换为int。而较新版本则从1个相同类型的元素列表进行复制构造或移动构造。

缺陷报告直到C++14出版后才得到解决,似乎对于gcc 4来说太晚了。


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