出于内存管理的目的,我正在尝试实现某种包装模板:
template<typename T>
class Foo {
T * var;
bool cpy;
Foo(T * inp, bool cpy): var(inp), cpy(cpy) {}
public:
// named ctors
static Foo<T> * newRef(T * inp){
return new Foo(inp, false);
}
static Foo<T> * newCpy(const Foo<T> * foo){
return new Foo(new T(*(foo->var)), true);
}
/* How to add cv variations to newCpy ? */
~Foo(){
if (cpy) delete var;
}
};
我正在寻找一种在newCpy()
中添加简历变量的方法,例如Foo<int>::newCpy(Foo<const int> *)
和Foo<const int>::newCpy(Foo<int> *)
。我的尝试看起来像这样:
template<typename T>
class Foo {
using mT = typename std::remove_cv<T>::type;
// T = const int -> mT = int
/* ... */
static Foo<T> * newCpy(const Foo<mT> * foo){
return new Foo(new T(*(foo->var)), true);
}
};
但是,由于两个原因,该方法不起作用:
如果T
不是const
,则mT
将与T
相同,并且两个newCpy
将具有完全相同的结果就是签名。
Foo<T>
无权访问Foo<mT>::var
有什么办法解决吗?
答案 0 :(得分:1)
使用元函数conditional
:https://en.cppreference.com/w/cpp/types/conditional
以下代码需要C ++ 17,但是要转换为C ++ 14,只需将_v
的出现替换为::value
。
template <typename T>
using invert_const =
std::conditional_t<std::is_const_v<T>, std::remove_const_t<T>, const T>;
对于这个特定问题,示例用例将为
static Foo<T> * newCpy(const Foo<invert_const<T>> * foo) {
return new Foo(new T(*(foo->var)), true);
}
在您给出的示例中,尚不清楚您是否打算删除易失性限定符,但是,如果我只是误解了预期的用例,则可能会发生类似的反转:
template <typename T>
using invert_volatile =
std::conditional_t<std::is_volatile_v<T>, std::remove_volatile_t<T>, volatile T>;
这些也可以组成
template <typename T>
using invert_cv = invert_volatile<invert_const<T>>;
然后可以按以下方式使用元功能invert_cv
static Foo<T> * newCpy(const Foo<invert_cv<T>> * foo) {
return new Foo(new T(*(foo->var)), true);
}