[英]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.