以给定参数调用构造函数的可变参数函数

时间:2019-07-12 07:03:21

标签: c++ function templates constructor variadic

需要创建具有不同arg类型的可变参数template<T>函数,该函数将使用给定参数调用T的构造函数,有点像创建线程时一样,但是相反(创建线程时,其构造函数调用函数给定的功能指针)。

所以在伪代码中,它应该看起来像这样

template<typename T>
T* CreateNew( ARGS ) {
    return new T( ARGS );    //Constructor Gets Same Arguments That Were 
}                            //Passed To The Function

希望这种行为类似于创建线程时,当它们使用不同类型的参数(我不确定如何实现)调用函数时。

2 个答案:

答案 0 :(得分:3)

对我来说尚不完全清楚,但我认为您想查找可变参数模板,例如:

template <typename T, typename... Args>
T* CreateNew(Args... args) {
    return new T(args...);
}

添加示例:

#include <iostream>

class A {
    public:
    A(int a){
        std::cout<<__PRETTY_FUNCTION__<<std::endl;
    }
    A(std::string a){
        std::cout<<__PRETTY_FUNCTION__<<std::endl;
    }
    A(int a,std::string b){
        std::cout<<__PRETTY_FUNCTION__<<std::endl;
    }
};

template<typename T, typename... Args>
T* create(Args... args){
    return new T(args...);
}

int main(){
    A b(1);
    A c("a");
    A d(1,"a");
    A* bp = create<A>(1);
    A* cp = create<A>("a");
    A* dp = create<A>(1,"a");
    // This code leaks
    return 0;   
}

请注意,由于将更改保持在最低限度,因此我们仍在此处返回T*作为原始代码。在大多数情况下,这不是一个好主意,因为所有权是通过原始指针传递的。因此,如评论所建议,您可能希望使用std::unique_ptr,这将使您的CreateNew函数基本上等同于std::make_unique

答案 1 :(得分:2)

编写此函数的正确方法是

template <typename T, typename... Args>
T* CreateNew(Args&&... args) {
    return new T(std::forward<Args>(args)...);
}

在没有转发引用Args&&且没有std::forward的情况下,传递的参数的原始值类别将不会传播到T的构造函数中,从而导致潜在的性能和语义问题。 / p>