英文:
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 ). 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:
#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;
}
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& get_instance() {
static MyStruct instance = []() -> MyStruct {
MyStruct ret{ 15 };
g_entries.items[g_entries.count++] = &instance;
return ret;
}();
// Or if you don't otherwise need `ret`
static MyStruct instance = []{
g_entries.items[g_entries.count++] = &instance;
return MyStruct{ 15 };
}();
return instance;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论