模板化成员函数和参数转发
templated member function and argument forwarding
我在我的 c++ playground 中玩容器,我遇到了相当技术性的问题。
我正在尝试为容器实现一个 emplace 方法。现在它应该接受一个已经构建的元素并将其传递给分配器构造方法。
我最终得到了三种方法,模板化 emplaceA
和一对 emplaceB1
,emplaceB2
。所有工作都按预期进行。
我的问题是 emplaceA
没有明确说明 Arg
只能是 T
(这就是我想要的)。 emplaceB1
、emplaceB2
在两个不同的地方提供了几乎相同的实现(我认为这是一个缺陷)。
有解决办法吗?
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){
// ...
}
不要忘记包含 header <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){
// ...
}
我在我的 c++ playground 中玩容器,我遇到了相当技术性的问题。
我正在尝试为容器实现一个 emplace 方法。现在它应该接受一个已经构建的元素并将其传递给分配器构造方法。
我最终得到了三种方法,模板化 emplaceA
和一对 emplaceB1
,emplaceB2
。所有工作都按预期进行。
我的问题是 emplaceA
没有明确说明 Arg
只能是 T
(这就是我想要的)。 emplaceB1
、emplaceB2
在两个不同的地方提供了几乎相同的实现(我认为这是一个缺陷)。
有解决办法吗?
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){
// ...
}
不要忘记包含 header <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){
// ...
}