3

我有std::variant所有类都派生自同一个基础的地方。我想将变体转换为基础。

return std::visit( []( const Base& b ) { return b; }, v );

这会编译但会发出警告 C4172:返回局部变量或临时地址

有没有办法std::variant就地访问,而无需制作本地或临时副本?

或者,如果不可能,我该如何将值转换为void*我可以使用static_cast

更新:我认为这个例子应该很明显,但事实并非如此,这是完整的再现:

#include <variant>

struct Base {};
struct A : Base {};
struct B : Base {};

const Base& cast( const std::variant<A, B>& v )
{
    return std::visit( []( Base const& b ) { return b; }, v );
}

int main()
{
    std::variant<A, B> v{ A{} };
    const auto& b = cast( v );
}
4

1 回答 1

5

Lambda 具有返回类型推导,但它们通过值推导返回类型。就好像它们是一个返回的函数auto,而不是decltype(auto)。如果要通过引用返回,则需要指定返回类型。

因此,[](const Base& b) { return b; }按值返回,复制b. 显式指定返回类型以强制它通过引用返回:

const Base& cast( const std::variant<A, B>& v )
{
    return std::visit( []( Base const& b ) -> Base const& { return b; }, v );
}
于 2018-12-20T18:11:24.890 回答