一般问题:如果不考虑是否是一个好主意,如何将隐式转换运算符添加到已定义的类中?例如,假设我想要unique_ptr< T>隐式转换为T * ,但我不能只添加成员转换运算符,因为我无法更改unique_ptr类的定义。
选项:
我是否可以使用一些c ++巫毒来实现这一目标而不创建成员函数?
答案 - 远:否。
无法在代码中无法修改的类型中添加隐式转换。
只是......悲伤。
我可以从std :: unique_ptr派生并添加我自己的成员转换功能吗?这有什么严重的缺点吗?
答案 - 远:是(来自vsoftco)
下行尚未确定。到目前为止继承自std :: unique_ptr,继承其构造函数,并声明一个隐式转换运算符,几乎没有任何需要编写的代码。
我将不得不在余生中度过余生吗?
答案 - 远:我们会看到......
如果我可以选择2运行而没有任何严重的副作用或负担,我会测试一段时间并报告我是否认为值得。我们会看到!
示例代码:
#include <algorithm>
#include <memory>
#include <vector>
struct MyClass
{
MyClass(int v) : value(v) {}
int value;
};
int main()
{
auto vec = std::vector<std::unique_ptr<MyClass>>();
vec.push_back(std::make_unique<MyClass>(1));
vec.push_back(std::make_unique<MyClass>(2));
// error C2664: 'void (__vectorcall *)(MyClass *)' : cannot convert argument 1 from 'std::unique_ptr<MyClass,std::default_delete<_Ty>>' to 'MyClass *'
std::for_each(std::begin(vec), std::end(vec), [](MyClass* myClass)
{
myClass->value += 3;
});
}
答案 0 :(得分:5)
如果您不想使用std::unique_ptr<>::get()
功能,可以:
定义一个自由函数,它接受std::unique_ptr
并返回get
返回的原始指针,虽然我认为它不会让你的代码更好,例如:
// free function
template<typename T>
T* get_raw_ptr(const std::unique_ptr<T>& up)
{
return up.get();
}
unique_ptr
到原始指针的转换是可以的,但它们必须是显式的。隐式转换可能会导致许多令人头痛的问题,因为它们可能会在您最不期望的时候发生。
从std::unique_ptr
派生是一个坏主意,因为后者不能用作基类(没有虚拟析构函数)。通常,从标准库类派生是不好的。但是,如果您真的坚持,可以使用包装器来定义隐式转换运算符,例如:
// wrapper
template <class T, class Deleter = std::default_delete<T>>
class unique_ptr_wrapper: public std::unique_ptr<T, Deleter>
{
public:
using std::unique_ptr<T, Deleter>::unique_ptr; // inheriting base ctors
operator T* () const {return this->get();}
};
并且使用就像
一样 // wrapper usage:
unique_ptr_wrapper<int> upw{new int{42}};
int* p = upw; // implicit conversion OK