声明类型为 Returning 函数的未初始化自动变量

Declare uninitialized auto variables with type of Returning function

提问人:AndreiM 提问时间:10/13/2023 更新时间:10/13/2023 访问量:71

问:

我是尽可能多地使用的粉丝,但有一种情况到目前为止我没有解决方案。auto

在这种情况下,我必须在作用域之外声明变量,但在作用域内对其进行初始化,通常是 .下面是一个典型的例子:try/catch

std::vector<std::shared_ptr<Some::Custom::Type> Initialize()
{
    return {};
}

void Use()
{
    // delctype(Initialize) result; // not working
    // auto result; // completely different
    std::vector<std::shared_ptr<Some::Custom::Type> result // so much typing
    try
    {
        result = Initialize();
    }
    catch(...) {}
    ....
    
}

我知道您可以通过在范围内执行其余代码来避免此问题,但有时您需要这样做。 有没有办法在 C++20 之前实现成语?trydelctype(Initialize) result;

C++ 自动 decltype-auto

评论

0赞 John Doe 10/13/2023
如果它是您必须多次使用的类型,您不能为它使用更短的宏并使用它吗?#definetypedef
0赞 AndreiM 10/13/2023
这是一个通用的情况,有时它是一个向量、一个字符串、一个 ptr,以及我可能在大型代码库中调用的任何函数。
2赞 Vlad from Moscow 10/13/2023
@AndreiM decltype( Initialize() ) 结果呢?
0赞 Jarod42 10/13/2023
使用直接调用的 lambda?
1赞 mch 10/13/2023
decltype(Initialize()) result;作品: godbolt.org/z/KvY3r6sPq

答:

0赞 YSC 10/13/2023 #1

你基本上有三种方法。

1.decltype

给出变量应具有的类型的实际表达式:。注意:当函数需要大量参数时,这并不总是实用的。decltypedelctype(Initialize())

struct long_name {};

long_name initialize() { return {}; }

int main()
{
    decltype(initialize()) value;
    {
        value = initialize();
    }
}

(演示)


2.std::invoke_result

还有 std::invoke_result 如果你想构造一个复杂的特征。


3. 类型别名

作为最终的替代方法,类型别名有时是更好的解决方案:

using Types = std::vector<std::shared_ptr<Some::Custom::Type>;

评论

0赞 AndreiM 10/13/2023
谢谢。方法 1 是我真正想要的,而且我很接近,我只是错过了 paranthesis。但是,如果该方法有一些参数,我们又回到了方块 1:godbolt.org/z/rPseKGeT1
2赞 Nelfeal 10/13/2023 #2

decltype(Initialize)是函数的类型。您想获取表达式的类型,它只是返回类型:decltype(Initialize())Initialize()

decltype(Initialize()) result;

您也可以使用立即调用的 lambda:

auto result = []{
    try
    {
        return Initialize();
    }
    catch(...) {}
}();

演示

其他选项包括制作一个类型别名来缩短它,使用 std::invoke_result(尽管我认为这在这种情况下没有任何好处),或者,正如你提到的,将其余代码放在 try 块中;您甚至可以将整个函数放入函数中,并使用函数尝试块decltype

评论

0赞 AndreiM 10/13/2023
关于如何处理带有参数的方法的任何见解?Initialize
0赞 Jarod42 10/14/2023
捕获,还是将参数传递给 lambda?
0赞 Nelfeal 10/14/2023
@AndreiM 是什么阻止了你传递参数?下面是一个示例