获取经过RVO优化的静态变量的地址

huangapple go评论103阅读模式
英文:

Taking address of RVO-optimized static

问题

以下是您提供的代码的翻译部分:

在以下代码中,我试图注册一个单例实例到一个保存所有单例的全局数组中(在生产代码中,我可以根据模板参数实例化不同的单例,所以不用担心这个矛盾的问题 :))。我想知道的是,是否可以以某种方式获取 Lambda 表达式的返回类型的地址,而 Lambda 表达式应该已经被返回值优化,这样我就可以将它注册到全局条目数组中。

这是我目前的代码:

  1. #include <ranges>
  2. #include <cstdio>
  3. #include <cstdint>
  4. #include <iostream>
  5. namespace rng = std::ranges;
  6. struct MyStruct {
  7. uint32_t a = 0;
  8. };
  9. struct AllStructs {
  10. std::array<MyStruct*, 10> items = { 0 };
  11. std::size_t count = 0;
  12. } g_entries;
  13. auto get_instance() {
  14. static MyStruct instance = []() -> MyStruct{
  15. MyStruct ret{ 15 };
  16. g_entries.items[g_entries.count++] = &ret;
  17. return ret;
  18. }();
  19. return instance;
  20. }
  21. int main() {
  22. [[maybe_unused]] auto instance = get_instance();
  23. std::cout << "my a = " << instance.a << std::endl;
  24. std::cout << "my a from array = " << g_entries.items[0]->a << std::endl;
  25. }

输出结果:

  1. my a = 15
  2. my a from array = 0

至少目前看来,它不像这样工作,因为从数组中获取的条目仍然是0。我该如何解决这个问题?

更多注释

  • 我不能在此代码部分使用动态内存分配!
英文:

In the following code I try to register a singleton instance with a global array that keeps all singletons (in production code I can instantiate different singletons based on template parameters so don't worry about this paradox 获取经过RVO优化的静态变量的地址 ). What I wanted to know is if I can somehow get the address of to-be return type of the lambda which is ought to be return value optimized anyway, so I can register it with the global entries array.

Here's what I've got:

Demo

  1. #include &lt;ranges&gt;
  2. #include &lt;cstdio&gt;
  3. #include &lt;cstdint&gt;
  4. #include &lt;iostream&gt;
  5. namespace rng = std::ranges;
  6. struct MyStruct {
  7. uint32_t a = 0;
  8. };
  9. struct AllStructs {
  10. std::array&lt;MyStruct*, 10&gt; items = { 0 };
  11. std::size_t count = 0;
  12. } g_entries;
  13. auto get_instance() {
  14. static MyStruct instance = []() -&gt; MyStruct{
  15. MyStruct ret{ 15 };
  16. g_entries.items[g_entries.count++] = &amp;ret;
  17. return ret;
  18. }();
  19. return instance;
  20. }
  21. int main() {
  22. [[maybe_unused]] auto instance = get_instance();
  23. std::cout &lt;&lt; &quot;my a = &quot; &lt;&lt; instance.a &lt;&lt; std::endl;
  24. std::cout &lt;&lt; &quot;my a from array = &quot; &lt;&lt; g_entries.items[0]-&gt;a &lt;&lt; std::endl;
  25. }

Output:

  1. my a = 15
  2. my a from array = 0

It doesn't work like this at least, as the entry gleaned from the array is still 0. How can I work around this?

Further notes:

  • I can't use dynamic memory allocation in this code section!

答案1

得分: 2

NRVO(命名返回值优化)不是强制的。但你可以直接获取结果对象的地址:

  1. auto& get_instance() {
  2. static MyStruct instance = []() -> MyStruct {
  3. MyStruct ret{ 15 };
  4. g_entries.items[g_entries.count++] = &instance;
  5. return ret;
  6. }();
  7. // 或者如果你不需要`ret`
  8. static MyStruct instance = []{
  9. g_entries.items[g_entries.count++] = &instance;
  10. return MyStruct{ 15 };
  11. }();
  12. return instance;
  13. }
英文:

NRVO is not mandatory. But you can just take the address of the result object directly:

  1. auto&amp; get_instance() {
  2. static MyStruct instance = []() -&gt; MyStruct {
  3. MyStruct ret{ 15 };
  4. g_entries.items[g_entries.count++] = &amp;instance;
  5. return ret;
  6. }();
  7. // Or if you don&#39;t otherwise need `ret`
  8. static MyStruct instance = []{
  9. g_entries.items[g_entries.count++] = &amp;instance;
  10. return MyStruct{ 15 };
  11. }();
  12. return instance;
  13. }

huangapple
  • 本文由 发表于 2023年5月31日 23:27:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76375114.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定