Class 包含一个引用或一个有限数量的值 类
Class containing a reference OR a value of finite number of classes
我正在制作一些分配大量内存的 classes。
因此,我需要尽量减少复制操作的次数。
在处理它时,我希望如果我有一个包含类型 (T
) 或引用 (T&
) 的模板 class,而不是两者都包含,这样我可以编写如下代码:
template<typename T>
class EITHER {
/* some code */
};
class A { /* some code */ };
void f(A &a) { /* some code changing `a` */ }
int main() {
A a(42);
std::vector<EITHER<A>> v;
v.emplace_back(a); /* stored as a reference */
v.emplace_back(A(72)); /* stored as a value (possibly moved) */
f(a); /* okay. */
f(v[0]); /* okay, modifies `a` through a reference stored in `EITHER<A>`. */
f(v[1]); /* okay, modifies the value stored in `EITHER<A>`. */
{
A b(3);
v.emplace_back(b); /* stored as a reference */
} // Now `b` is destructed, `v[2]` holds the latest value (not reference) of `b`.
f(v[2]); /* okay, modifies the value stored in `EITHER<A>`. */
}
我很确定这在很多情况下都会有用,但我不知道如何实现它。
std::variant
无法存储引用。
std::optional<T>
和 T*
可能会完成这项工作,但我很确定应该有一种方法可以像 std::optional
那样处理这个问题。如果std::optional
存储或不存储类型,EITHER
将只存储类型T
或类型T&
。
- 最后,好像要备注一下原变量是否被析构了,但是不修改就可以吗
A
?
请记住,EITHER
将应用有限多个 class,如果这有用的话。
我希望我能得到这个问题的任何解决方案或反馈。谢谢。
p.s。瞄准c++20.
引用具有重要的 属性,它们应该始终有效(如果您不搞砸的话),这可以将它们与指针区分开来,指针也可能是 nullptr
.
您需要在内部使用指针。您可以在指针和引用之间来回转换,因此您仍然可以获取引用并始终传递引用。
问题在于您在 Either
class 中引入了 可选所有权 。预计会有很多编程错误。它已经从您的示例 b
开始,您希望在其中传递一个引用,据称稍后会神奇地转换为一个值。
我建议研究 unique_ptr
如何解决您的问题。使用唯一指针明确定义容器将取得其内容的所有权。调用者可以将现有对象包装在 unique_ptr
中,或者如果它们是在堆栈上创建的,则将它们移动到 make_unique()
中,以及使用 make_unique()
创建新对象。最后,你不会有包装器 class 或任何东西,每个精通 C++11 的人都应该能够理解 std::vector<std::unique_ptr<A>> v;
是如何工作的。
我正在制作一些分配大量内存的 classes。 因此,我需要尽量减少复制操作的次数。
在处理它时,我希望如果我有一个包含类型 (T
) 或引用 (T&
) 的模板 class,而不是两者都包含,这样我可以编写如下代码:
template<typename T>
class EITHER {
/* some code */
};
class A { /* some code */ };
void f(A &a) { /* some code changing `a` */ }
int main() {
A a(42);
std::vector<EITHER<A>> v;
v.emplace_back(a); /* stored as a reference */
v.emplace_back(A(72)); /* stored as a value (possibly moved) */
f(a); /* okay. */
f(v[0]); /* okay, modifies `a` through a reference stored in `EITHER<A>`. */
f(v[1]); /* okay, modifies the value stored in `EITHER<A>`. */
{
A b(3);
v.emplace_back(b); /* stored as a reference */
} // Now `b` is destructed, `v[2]` holds the latest value (not reference) of `b`.
f(v[2]); /* okay, modifies the value stored in `EITHER<A>`. */
}
我很确定这在很多情况下都会有用,但我不知道如何实现它。
std::variant
无法存储引用。std::optional<T>
和T*
可能会完成这项工作,但我很确定应该有一种方法可以像std::optional
那样处理这个问题。如果std::optional
存储或不存储类型,EITHER
将只存储类型T
或类型T&
。- 最后,好像要备注一下原变量是否被析构了,但是不修改就可以吗
A
?
请记住,EITHER
将应用有限多个 class,如果这有用的话。
我希望我能得到这个问题的任何解决方案或反馈。谢谢。
p.s。瞄准c++20.
引用具有重要的 属性,它们应该始终有效(如果您不搞砸的话),这可以将它们与指针区分开来,指针也可能是 nullptr
.
您需要在内部使用指针。您可以在指针和引用之间来回转换,因此您仍然可以获取引用并始终传递引用。
问题在于您在 Either
class 中引入了 可选所有权 。预计会有很多编程错误。它已经从您的示例 b
开始,您希望在其中传递一个引用,据称稍后会神奇地转换为一个值。
我建议研究 unique_ptr
如何解决您的问题。使用唯一指针明确定义容器将取得其内容的所有权。调用者可以将现有对象包装在 unique_ptr
中,或者如果它们是在堆栈上创建的,则将它们移动到 make_unique()
中,以及使用 make_unique()
创建新对象。最后,你不会有包装器 class 或任何东西,每个精通 C++11 的人都应该能够理解 std::vector<std::unique_ptr<A>> v;
是如何工作的。