使用decltype编写复制和移动函数

时间:2013-02-13 21:38:07

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

我的代码有几个实例,当遇到T&&amp ;;或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 */
}

或者有更好的方法来编写几乎相同的移动和复制功能吗?

1 个答案:

答案 0 :(得分:5)

T&&功能中使用std::forward()并弃掉const T&功能:

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