创建一个可以通过赋值初始化但不可复制的类型
creating a type which can be initialized with assignment, but is not copyable
我希望创建一个类型,该类型可以通过另一个类型的赋值进行初始化,但不能复制。这个想法与作用域智能指针的想法类似,因为我希望这种类型的对象在其生存期内拥有资源,但我也希望能够使用赋值语法。所以在简介中,这就是我想要的:
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&)":/usr/include/boost/non-copyable。hpp:27:7:错误:'boost::noncopyable_::noncopiable::noncompaable(constboost::noncopyable_::noncopiable&)'是私人测试。抄送:6:30:错误:在此上下文中test.cc:In函数'int main()':test.cc:20:12:注意:合成方法"T::T(const T&)"首先需要
注意:C++11的移动功能对我来说是不可选择的,因为它必须能够使用不支持C++11的相对较旧版本的gcc进行编译
由于缺乏对C++11的支持,我不确定是否有"好"的解决方案。但我想我会问的。
如果我从评论中的理解是正确的,你想要这样的东西:
U* create_T() { return new U; }
if (T t = create_T())
{
// do something with t
}
这里的问题已经在评论中提到了:这个语法T t = u
只是在调用复制构造函数。如果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);
....
}
顺便说一句,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
这是我的表意研究。。。
- 是否可以初始化不可复制类型的成员变量(或基类)
- 直接初始化不可复制、不可移动的成员,而不使用聚合初始化
- 初始化没有复制构造的类
- 直接列表初始化和复制列表初始化之间的差异
- 为什么对象的初始化调用复制构造函数
- 大括号初始化可防止非常量使用临时
- 初始化不可复制、不可移动、显式构造类型的成员数组
- 初始化不可复制和不可移动类的元组
- 显式强制转换、直接初始化和复制初始化之间的行为不同
- 是直接初始化还是复制初始化
- 直接初始化和复制参考初始化
- 为什么标准区分直接列表初始化和复制列表初始化?
- 不带操作员的对象的数组初始化,复制构造函数或默认构造函数和运行时参数
- C 带有什么默认复制构造函数使用什么初始化基本复制构造函数
- 有没有一种非重复的方法允许程序员在成员初始化的复制和移动语义之间进行选择
- C++为什么矢量初始化调用复制构造函数
- 自动变量初始化和复制/移动构造函数
- 如何使用运行时选择基 CTOR 初始化不可复制的基类
- 使用“auto”进行初始化需要复制构造函数
- 使用指向对象的指针初始化不可复制的第三方基类