简体   繁体   English

如何在模板类中返回成员变量的副本?

[英]How do I return a copy of a member variable in a template class?

Template newbie here. 模板新手在这里。 I'm playing with the following test class: 我正在玩以下测试课程:

template<typename T>
class Container
{
public:

    Container(T t) : m_t(t) {}

    T clone()
    {
        return m_t;
    }

private:

    T m_t;
};

The clone() method returns a copy of the member variable. clone()方法返回成员变量的副本。 Obviously, this doesn't work as intended if T is a pointer, eg: 显然,如果T是一个指针,这将无法正常工作,例如:

Container<SomeClass*> container(new SomeClass());

The clone() method would simply return a pointer and not a full clone. clone()方法将只返回一个指针,而不是完整的克隆。 I'm aware of the beauty of if constexpr but unfortunately I'm stuck with a C++14 compiler. 我知道if constexpr但不幸的是我只能使用C ++ 14编译器。 I would like to keep my class generic so that it would also work with pointers. 我想让我的类通用,以便它也可以与指针一起使用。 Should I create two different methods? 我应该创建两种不同的方法吗? Can SFINAE be of any help here? SFINAE可以帮上什么忙吗?

To specialize the entire class, as the other answer suggests, you might need to duplicate a lot of code (not a good thing). 如另一个答案所示,要使整个类专业化,您可能需要复制很多代码(不是一件好事)。

Instead, I'd suggest good ol' tag dispatch : 相反,我建议进行良好的标签分发

template<typename T>
class Container
{
    T clone_low(std::false_type)
    {
        return m_t;
    }

    T clone_low(std::true_type)
    {
        return new std::remove_pointer_t<T>(m_t);
    }

  public:
    Container(T t) : m_t(t) {}

    T clone()
    {
        return clone_low(std::is_pointer<T>{});
    }

  private:
    T m_t;
};

You can use a partial specialization of the class. 您可以使用该类的部分专业化 For example 例如

#include <iostream>

template<typename T>
class Container
{
public:
    Container(T t) : m_t(t) {}
    T clone()
    {
        return m_t;
    }

private:

    T m_t;
};

template<typename T>
class Container<T*>
{
public:
    Container(T* t) : m_t(new T(*t)) {}
    T* clone()
    {
        return new T(*m_t);
    }
    ~Container() { delete m_t; }

private:
    T* m_t;
};

int main()
{
    std::cout << Container<int>(10).clone() << '\n';

    int x = 20;
    Container<int*> c(&x);

    int* p = c.clone();
    std::cout << *p << '\n';

    delete p;
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM