【问题标题】:c++11 invoke a type conversion while moving an objectc++11在移动对象时调用类型转换
【发布时间】:2018-12-13 21:34:16
【问题描述】:

我有一个简单的代码,我在 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'

显式包裹(Packet&& object, int ts) : item{std::move(object)}

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

【问题讨论】:

  • 你为什么不直接写using buffer_t = void const *;
  • 也许这只是 gcc 4 中的一个错误
  • 我实际上是从另一个文件中复制的,void const * 更有意义,你说得对
  • @M.M:我认为这也是一个编译器错误,你能想出一个解决方法吗?

标签: c++ c++11


【解决方案1】:

看起来这个 GCC 版本不喜欢大括号初始化 item{std::move(object)}。不过,它使用 item(std::move(object)) 编译。

live example

【讨论】:

    【解决方案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 来说似乎为时已晚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-12-27
      • 1970-01-01
      • 1970-01-01
      • 2013-06-16
      • 2012-07-02
      • 2015-10-10
      相关资源
      最近更新 更多