C++模板函数中临时变量初始化问题
迷茫
迷茫 2017-04-17 15:25:21
0
3
712

有一个模板函数

template<typename T>
void function(T num){
    T tmp;
    memset(&tmp,0,sizeof(tmp));    //现在我是这么初始化的
}

然后我需要在函数里定义一个临时变量

T tmp

但这个T有可能是类类型(string), 也可能是内建类型(int, double)
那我要怎么初始化?
现在我是用memset()初始化的;
但如果sum这对象不在一块连续内存或者他定义时会初始化一些特殊成员, 这种方法就不行...

迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回覆(3)
大家讲道理

c++11的統一初始化:

T tmp {};

以前應該可以寫:

T tmp = T();
小葫芦

@Shihira

呃呃
Peter_Zhu

我理解題主的意思是能用0這個參數初始化的就盡量用0初始化,其它不行的就用預設構造函數。

template<typename T, typename Int = int>
T init_obj(Int) {
    return T{};
};

template<typename T, typename Enable = decltype(T(0.f))>
T init_obj(int) {
    return T(0);
};

int main()
{
    int i = init_obj<int>(0);
    float f = init_obj<float>(0);
    string s = init_obj<string>(0);
    vector<int> v = init_obj<vector<int>>(0);

    cout << i << endl; // 0
    cout << f << endl; // 0
    cout << s << endl; //
    cout << v.size() << endl; // 0
}

這裡有幾個點,一個是不能直接T tmp,因為Scalar Type會不初始化以至於直接使用棧當中的垃圾數據,以至於其數據不是0。二是不能用memset這種C的方法,因為C++的物件很多時候預設構造會分配內存,如果把指標置零會產生段錯誤或記憶體洩漏。三是這裡因為直接回傳一個對象,如果T沒有移動構造函數可能會降低效能。

上面這個寫法的原理是這樣的。利用Int和int的差別,因為C++在模板決策的時候會優先選擇特化程度更高的函數(或曰重載過的函數),所以下面一個init_obj比上面的更優先。 Enable用於對不能用0初始化的型別產生推導錯誤,C++的SFINAE政策將其轉移到上面一個init_obj;這裡用0.f是因為整型類型會隱式轉換到指針,但是float不會,而float也可以隱式轉換到任意一種數字類型。

個人覺得自己寫得很難看,求更好的寫法(

C++11的場合,樓上的寫法是很棒的:)

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板