【问题标题】:Using decltype to write copy and move functions使用 decltype 编写复制和移动函数
【发布时间】:2013-01-29 14:15:51
【问题描述】:

我的代码有几个实例,其中函数在遇到 T&& 或 const T& 时的反应略有不同,但是函数本身很长(注意 T 只是一些对象类型)。例如:

void push_back(const T& newt){
    /* code block X */
    new (ptr) T(newt);
    /* code block Y */
}

void push_back(T&& newt){
    /* code block X */
    new (ptr) T(std::move(newt));
    /* code block Y */
}

是否可以按照这个伪代码的行写一些东西:

template<typename S>
void push_back(S newt){
    /* code block X */
#if decltype(newt)==T&&
    new (ptr) T(std::move(newt));
#else
    new (ptr) T(newt);
#endif
    /* code block Y */
}

或者有没有更好的方法来编写几乎相同的移动和复制函数?

【问题讨论】:

    标签: c++ templates c++11 move-semantics decltype


    【解决方案1】:

    T&amp;&amp;函数中使用std::forward()并丢弃const T&amp;函数:

    template <typename T>
    void push_back(T&& newt){
        /* code block X */
        new (ptr) typename std::remove_reference<T>::type(std::forward<T>(newt));
        /* code block Y */
    }
    

    std::forward() 将传递给newt,就像传递给push_back() 一样。结果:

    • T 的复制构造函数在 push_back() 传递左值时使用,或者
    • T 的移动构造函数在 push_back() 被传递一个右值时被使用。

    http://ideone.com/HjOrap 上查看在线演示。

    请注意,如果push_back() 是独立函数或非模板类的成员函数,则这是正确的。如果它是模板类成员函数,则函数本身必须接受除了类模板类型之外的模板类型,因为此行为取决于 T 是推导类型。

    请参阅 Scott Meyers 的 Universal References

    【讨论】:

    • 我想我不太明白你的意思。虽然这对于做类似 {string t="hi"; 的事情很好。 push_back(std::move(t));},如果您尝试执行 {string t="hi"; 则不会编译push_back(t);};编译器给出了一些奇怪的错误。这个想法是在给定不同输入的情况下调用复制构造函数或移动构造函数。
    • 这是无法编译的代码:docs.google.com/file/d/0B7yGmb99B5encmVuREx3eUVXUEE/edit(顺便说一句,有没有更好的发布代码的方法?)
    • @Aggieboy,编译但有运行时错误的代码版本:ideone.com/BrB6gK 您可能想针对运行时错误发布另一个问题,我不确定并且没有太多的安置经验new
    • 除了std::remove_reference 之外还有一个std::remove_cv 怎么样,或者这是不必要的?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-28
    • 2016-04-20
    • 2013-11-05
    • 2015-08-14
    • 1970-01-01
    • 2017-01-18
    相关资源
    最近更新 更多