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

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

Taking address of RVO-optimized static

问题

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

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

这是我目前的代码:

#include <ranges>
#include <cstdio>
#include <cstdint>
#include <iostream>

namespace rng = std::ranges;

struct MyStruct {
    uint32_t a = 0;
};

struct AllStructs {
    std::array<MyStruct*, 10> items = { 0 };
    std::size_t count = 0;
} g_entries;

auto get_instance() {
    static MyStruct instance = []() -> MyStruct{
        MyStruct ret{ 15 };
        g_entries.items[g_entries.count++] = &ret;
        return ret;
    }();

    return instance;
}

int main() {
    [[maybe_unused]] auto instance = get_instance();

    std::cout << "my a = " << instance.a << std::endl;
    std::cout << "my a from array = " << g_entries.items[0]->a << std::endl;
}

输出结果:

my a = 15
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

#include &lt;ranges&gt;
#include &lt;cstdio&gt;
#include &lt;cstdint&gt;
#include &lt;iostream&gt;

namespace rng = std::ranges;

struct MyStruct {
    uint32_t a = 0;
};

struct AllStructs {
    std::array&lt;MyStruct*, 10&gt; items = { 0 };
    std::size_t count = 0;
} g_entries;

auto get_instance() {
    static MyStruct instance = []() -&gt; MyStruct{
        MyStruct ret{ 15 };
        g_entries.items[g_entries.count++] = &amp;ret;
        return ret;
    }();

    return instance;
}

int main() {
    [[maybe_unused]] auto instance = get_instance();

    std::cout &lt;&lt; &quot;my a = &quot; &lt;&lt; instance.a &lt;&lt; std::endl;
    std::cout &lt;&lt; &quot;my a from array = &quot; &lt;&lt; g_entries.items[0]-&gt;a &lt;&lt; std::endl;
}

Output:

my a = 15
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(命名返回值优化)不是强制的。但你可以直接获取结果对象的地址:

auto& get_instance() {
    static MyStruct instance = []() -> MyStruct {
        MyStruct ret{ 15 };
        g_entries.items[g_entries.count++] = &instance;
        return ret;
    }();

    // 或者如果你不需要`ret`
    static MyStruct instance = []{
        g_entries.items[g_entries.count++] = &instance;
        return MyStruct{ 15 };
    }();

    return instance;
}
英文:

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

auto&amp; get_instance() {
    static MyStruct instance = []() -&gt; MyStruct {
        MyStruct ret{ 15 };
        g_entries.items[g_entries.count++] = &amp;instance;
        return ret;
    }();

    // Or if you don&#39;t otherwise need `ret`
    static MyStruct instance = []{
        g_entries.items[g_entries.count++] = &amp;instance;
        return MyStruct{ 15 };
    }();

    return instance;
}

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:

确定