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

时间:2016-09-12 14:53:07

标签: c++ templates perfect-forwarding

我在c ++游乐场玩容器,遇到了技术问题。

我正在尝试为容器实现一个emplace方法。现在它应该采用一个已构造的元素并将其传递给allocator构造方法。

我最终得到了三种方法,模板emplaceA和一对emplaceB1emplaceB2。一切按预期工作。

我的问题是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));};
...
};

1 个答案:

答案 0 :(得分:0)

要限制模板化功能,您可以使用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){
    // ...
}