函數模板在調用函數的時候, 由於實參(argument)轉換形參(parameter)的時候, 會發生改變, 導致無法保留原實參的資訊, 即推進(forward)問題;
主要包括: 引用和右值;引用, 即因為模板參數非引用, 導致複製操作, 無法提供參考型別;右值, 即因為模板參數只能轉換為左值, 無法提供右值;
解決方案:
引用: 使用右值參數(T&& t), 可以保證傳遞引用不發生改變;
右值:使用右值參數, 再使用forward()函數(#include<utility>), 可以把實參轉換為初始類型, 左值或右值;
更多精彩內容:http://www.bianceng.cnhttp://www.bianceng.cn/Programming/cplus/
具體參見代碼注釋, 及輸出.
代碼如下:
/* * cppprimer.cpp * * Created on: 2013.11.28 * Author: Caroline */ #include <iostream> #include <utility> void f (int v1, int &v2) { std::cout << v1 << " " << ++v2 << std::endl; } void g (int &&i, int &j) //i為右值 { std::cout << i << " " << j << std::endl; } template <typename F, typename T1, typename T2> void flip1 (F f, T1 t1, T2 t2) { f(t2, t1); //反序 } template <typename F, typename T1, typename T2> void flip2 (F f, T1&& t1, T2&& t2) //右值傳遞, 保證引用性 { f(t2, t1); //反序 } template <typename F, typename T1, typename T2> void flip3 (F f, T1&& t1, T2&& t2) //右值傳遞, 保證引用性 { f(std::forward<T2>(t2), std::forward<T1>(t1)); //反序 } int main (void) { int i(10), j(10); f (42, i); //i傳遞引用發生改變 flip1 (f, j, 42); //j傳遞在flip1傳遞時是複製, 不發生改變 std::cout << "flip 1 : i = " << i << std::endl; std::cout << "flip 1 : j = " << j << std::endl; flip2 (f, j, 42); //j傳遞在flip1傳遞時是複製, 不發生改變 std::cout << "flip2 : j = " << j << std::endl; g (42, i); //可以傳遞 //不能傳遞, 因為j在傳遞時變成左值引用, 無法賦值右值 //cannot bind 'int' lvalue to 'int&&' //flip1 (g, j, 42); flip3 (g, j, 42); //forward函數保證傳遞所有資訊 return 0; }
輸出:
42 11 42 11 flip 1 : i = 11 flip 1 : j = 10 42 11 flip2 : j = 11 42 11 42 11
作者:csdn部落格 Spike_King