简体   繁体   English

带指针的 C++ 嵌套指定初始值设定项

[英]C++ nested designated initializer with pointer

I thought it would be useful to be able to initialize a struct that references another struct with a pointer, using the designated initializer.我认为能够使用指定的初始化程序初始化一个引用另一个结构体的结构体会很有用。 Such a pattern often happens in some APIs (eg, Vulkan).这种模式经常发生在某些 API(例如 Vulkan)中。 For instance, consider the following structs:例如,考虑以下结构:

struct A {
    int v;
};

struct B {
    int v;
    A* a;
};

struct C {
    B* b;
};

and a function taking C as an argument和一个以C为参数的函数

void func(const C& c) {}

I came up with an approach using unmove() ( ref ) function that converts rvalue to lvalue:我想出了一种使用unmove() ( ref ) 函数将右值转换为左值的方法:

template <typename T>
T& unmove(T&& v) { return v; }

Using this function, the nested initialization can be written by使用这个函数,嵌套的初始化可以写成

func({
    .b = &unmove(B{
        .v = 1,
        .a = &unmove(A{
            .v = 2
        })
    })
});

My question: Is it a valid usage of the function in terms of the standard?我的问题:就标准而言,它是函数的有效用法吗? Or am I missing something?或者我错过了什么?

This is safe as long as the function doesn't store or return the referred object or its address or the nested pointers for later usage.只要函数不存储或返回引用的对象或其地址或嵌套的指针以供以后使用,这就是安全的。 The temporary objects will be destroyed at the end of the full expression and as such the mentioned stored / returned references / pointers would be invalid.临时对象将在完整表达式结束时销毁,因此提到的存储/返回的引用/指针将无效。

[class.temporary] [类.临时]

... Temporary objects are destroyed as the last step in evaluating the full-expression ([intro.execution]) that (lexically) contains the point where they were created. ... 临时对象被销毁作为评估完整表达式 ([intro.execution]) 的最后一步,该表达式(词法上)包含它们的创建点。 ... ...

I'd make it addressof_rvalue :我会把它addressof_rvalue

template <typename T>
T* addressof_rvalue(T&& v) { return std::addressof(v); }
template <typename T>
T* addressof_rvalue(T& v) = delete;

it is safe, so long as the pointer doesn't outlive the function you are calling.它是安全的,只要指针不超过您正在调用的函数。

func({
    .b = addressof_rvalue(B{
        .v = 1,
        .a = addressof_rvalue(A{
            .v = 2
        })
    })
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM