在C ++中转发params

时间:2015-04-23 17:03:48

标签: c++ class templates c++11 c++-standard-library

我有一些类和包装它。例如:

$(document).on('click', ".add-gc-field", function () {
    if ($(this).next('ul').length) {
        console.log(this);
        $(this).next('ul').append('<li><input /><p class="add-gc-field"><i class="fa fa-plus"></i></p> </li>');
    } else {
        console.log(this)
        $(this).after('<ul><li><input /><p class="add-gc-field"><i class="fa fa-plus"></i></p> </li></ul>');
    }
});

如果#include <iostream> #include <string> template<typename T> class inner { public: void f(T& v) { std::cout<<"lvalue: "<<v<<std::endl;} void f(T&& v) { std::cout<<"rvalue: "<<v<<std::endl;} }; template<typename T> class wrapper { public: template<typename _T> void f(_T&& v) { i.f(std::forward<T>(v)); } //(1) private: inner<T> i; }; int main() { wrapper<std::string> c; //inner<std::string> c; c.f("r"); std::string s = "l"; c.f(s); } c输出正确,则为

inner

但当rvalue: r lvalue: l 输出c不正确时:

wrapper

为什么l值变为r值?

rvalue: r rvalue: l wrapper f(1)定义的区别是:

    template<typename _T>
    void f(_T v) { i.f(std::forward<T>(v)); } //without &&

1 个答案:

答案 0 :(得分:3)

因为你正在做:

template<typename _T>
void f(_T&& v) { i.f(std::forward<T>(v)); } //(1)
                                  ^
                                  T, not _T

您始终只使用T,而不是推断的类型的v。为了更加清晰,你实际上在做:

template <typename _T>
void f(_T&& v) {
    i.f(std::forward<std::string>(v));
}

std::forward<std::string>(v)的类型为string&&

关于你的第二个问题:

template<typename _T>
void f(_T v) { i.f(std::forward<T>(v)); } //without &&

由于此处_T永远不会推断为引用类型,std::forward<T>(v)将等同于std::move(v) - 它只是一个转换为右值引用。