我希望创建一个类型,可以使用其他类型的赋值进行初始化,但不能复制。这个想法类似于范围内的智能指针,因为我希望这种类型的对象在其生命周期内拥有一个资源,但我也希望能够使用赋值语法。所以在概要中,这就是我想要的:
T x = new U; // allowed
T y(new U); // allowed
T z = x; // not allowed
T x2(x) // not allowed
这是我到目前为止所尝试的......
#include <boost/noncopyable.hpp>
class U {};
class T : boost::noncopyable {
public:
T(U *p) : p_(p) {
}
~T() {
delete p_;
}
operator bool() const { return p_ != 0; }
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
//T z = x; // not allowed
//T x2(x) // not allowed
}
不幸导致错误:
$ g ++ test.cc -o test /usr/include/boost/noncopyable.hpp:副本 构造函数'T :: T(const T&amp;)':/ usr / include / boost / noncopyable.hpp:27:7: 错误:'boost :: noncopyable _ :: noncopyable :: noncopyable(const boost :: noncopyable _ :: noncopyable&amp;)'是private test.cc:6:30:错误: 在这个上下文中test.cc:在函数'int main()'中:test.cc:20:12: 注意:这里首先要求合成方法'T :: T(const T&amp;)'
注意:C ++ 11的移动功能对我来说是一个非选项,因为它必须能够使用相对较旧版本的gcc编译,而该版本没有C ++ 11支持。
由于缺乏C ++ 11支持,我不确定是否有“好”的解决方案。但我想我会问。
答案 0 :(得分:1)
如果我对评论的理解是正确的 - 你想要这样的东西:
U* create_T() { return new U; }
if (T t = create_T())
{
// do something with t
}
此处的问题已在评论中提及:此语法T t = u
只是调用复制构造函数。如果您的类型为T
,则相当于:T t(u)
。如果您的示例中的u
是另一种可转换为T
(here by T::T(U*)
)的类型,那么它实际上就是:T t(T(u))
。所以这里有编译器抱怨的复制构造函数。
没有解决方案,因为这不是有效的if
语法:
if (T i(create_T())) {}
但是如果没有好的建议,我不会写下所有这些;)
您可以使用以下语法忘记复制构造函数的问题:
if (U* u = create_T()) {
T t(u);
....
}
BTW,std::auto_ptr
与您的T
类型存在同样的问题。只需向T(U*)
构造函数添加显式内容,您就会看到与auto_ptr
的相似性:
class U {};
class T : boost::noncopyable {
public:
explicit T(U *p) : p_(p) {
}
~T() {
delete p_;
}
private:
U *p_;
};
int main() {
T x = new U; // allowed
T y(new U); // allowed
std::auto_ptr<U> a = new U;
std::auto_ptr<U> b(new U);
}
结果:
prog.cpp:25: error: conversion from ‘U*’ to non-scalar type ‘T’ requested
prog.cpp:27: error: conversion from ‘U*’ to non-scalar type ‘std::auto_ptr<U>’ requested
这是我ideone的研究......