C++模板函数中临时变量初始化问题

发布于 2022-09-04 13:00:06 字数 345 浏览 22 评论 0

有一个模板函数

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

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

T tmp

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

临风闻羌笛 2022-09-11 13:00:06

c++11的统一初始化:

T tmp {};

以前应该可以写:

T tmp = T();
天冷不及心凉 2022-09-11 13:00:06

@Shihira

template <typename T,bool>
struct init_obj{

    T operator()(int value) {
        return T(value);
    }

};

template<typename T>
struct init_obj<T,false> {
    T operator()(int value) {
        return T{};
    }
};

template<typename T>
T rt(int value) {

    return init_obj<T, is_convertible<T, int>::value>()(value);
}
橘香 2022-09-11 13:00:06

我理解题主的意思是能用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的场合,楼上的写法是很棒的:)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文