模板化的成员函数和参数转发

templated member function and argument forwarding

本文关键字:参数 转发 函数 成员      更新时间:2023-10-16

我正在我的c++游乐场中玩容器,我遇到了相当技术性的问题。

我正试图实现容器的放置方法。现在,它应该接受一个已经构造好的元素,并将其传递给allocator构造方法。

我最终有三个方法,模板化emplaceA和一对emplaceB1, emplaceB2。一切正常

我的问题是emplaceA没有明确说明Arg只能是T(这就是我想要的)。emplaceB1emplaceB2在两个不同的地方提供了几乎相同的实现(我认为这是一个缺陷)。

有解决方法吗?

template<class T, class A> class container {
public:
    using allocator_traits  = typename std::allocator_traits<A>;
...
    template<class Arg> void emplaceA (int n, Arg&& arg){
        allocator_traits::construct(allocator_, data_+n, std::forward<Arg>(arg));};
    void emplaceB1(int n, const T& t){
        allocator_traits::construct(allocator_, data_+n, t);};
    void emplaceB2(int n, T&& t){
        allocator_traits::construct(allocator_, data_+n, std::move(t));};
...
};

要限制模板化函数,可以使用sfinae来防止发送不需要的类型。

在下面的例子中,我们限制你的模板函数只有在Arg可转换为T时才可调用。注意,即使两种类型相同,is_convertible也可以工作。

template<class Arg, std::enable_if_t<std::is_convertible<Arg, T>::value, int> = 0>
void emplaceA(int n, Arg&& arg){
    // ...
}

不要忘记包含标题<type_traits>


当然,如果你想检查发送的类型是否严格是T,你可能想使用std::is_same和衰减类型。

template<class Arg, std::enable_if_t<std::is_same<std::decay_t<Arg>, T>::value, int> = 0>
void emplaceA(int n, Arg&& arg){
    // ...
}