2016-11-27 48 views
3

這個問題繼續到question。我不想混淆這個問題,因此寫了一個新問題。完美轉發的問題C++

修改後,我做了一個更改。現在我創建了一個不可複製的類,並嘗試將相同的類傳遞給Print()

#include<utility> 
#include<string> 
#include<tuple> 
#include<sstream> 

template<typename... Args> struct Helper_Class 
{ 
    std::tuple<Args...> argTuple; 
    Helper_Class(Args&&... args): 
        argTuple(std::make_tuple(std::forward<Args>(args)...)) 
    {} 
}; 

template<typename... Args> std::ostream& 
operator<< (std::ostream& os,Helper_Class<Args...> obj) 
{ 
    return os; 
} 

struct A { 
    friend int main(int argc, char **argv); 
    friend std::ostream & operator<<(std::ostream &os, const A &a) { 
     return os << a.i; 
    } 
    A(int i_) : i(i_) {} 
    A(const A &) = delete; 
    A &operator=(const A &) = delete; 
    const int i; 
}; 


template<typename...Args> 
auto Print(Args&&... args) 
{ 
    return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...); 
    //return Helper_Class<typename std::decay<Args>::type...>(std::forward<Args>(args)...); 
} 

template <typename... Ts> 
void test(Ts &&...params) { 
    std::stringstream s; 
    s <<Print(std::forward<Ts>(params)...); 
} 

int main(int argc, char **argv) 
{ 
    test(1,2,"foo", A(123)); 
} 

但現在我得到鏈接器錯誤。但我不應該得到一個,因爲我試圖實現移動語義。我越來越

錯誤是:

/tmp/cckfv4uI.o: In function `std::_Head_base<3ul, A, false>::_Head_base<A>(A&&)': 
forwarding.cpp:(.text._ZNSt10_Head_baseILm3E1ALb0EEC2IS0_EEOT_[_ZNSt10_Head_baseILm3E1ALb0EEC5IS0_EEOT_]+0x2a): undefined reference to `A::A(A const&)' 
collect2: error: ld returned 1 exit status 
+3

您沒有「A」的移動構造函數。 –

+0

ohh ..你可以在這種情況下提出一個出路嗎?如果我不能改變A類,測試函數,我想用l值和r值來調用測試。 –

+1

'A'沒有移動構造函數,那麼如何調用它?你必須添加一個'A(A &&)'或者將它包裝在一個智能指針中以便它能夠工作,否則你會得到一個複製構造函數調用。 – 0x499602D2

回答

1

因爲你只需要一個方式來引用的論點,你不需要完美轉發的。以下是一個示例:

#include<tuple> 
#include<sstream> 

template<typename Arg_Tuple> struct Helper_Class 
{ 
    Arg_Tuple argTuple; 
    Helper_Class(const Arg_Tuple &args): argTuple(args) {} 
}; 

template<typename Arg_Tuple> std::ostream& 
operator<< (std::ostream& os,Helper_Class<Arg_Tuple> /*obj*/) 
{ 
    return os; 
} 

struct A { 
    friend int main(); 
    friend std::ostream & operator<<(std::ostream &os, const A &a) { 
     return os << a.i; 
    } 
    A(int i_) : i(i_) {} 
    A(const A &) = delete; 
    A &operator=(const A &) = delete; 
    const int i; 
}; 


template<typename...Args> 
auto Print(const Args& ... args) 
{ 
    auto args_tuple = std::tie(args...); 
    return Helper_Class<decltype(args_tuple)>(args_tuple); 
} 

template <typename... Ts> 
void test(const Ts &...params) { 
    std::stringstream s; 
    s <<Print(params...); 
} 

int main() 
{ 
    test(1,2,"foo", A(123)); 
}