如何优雅地返回默认初始化的对象

How to elegantly return an object that is default-initialized?

本文关键字:初始化 对象 默认 返回 何优雅      更新时间:2023-10-16

>我有一个这样的类:

class VeryVeryVeryLongTypeName
{
    bool is_ok;
    VeryVeryVeryLongTypeName() : is_ok(false) {}
};
VeryVeryVeryLongTypeName f()
{
    VeryVeryVeryLongTypeName v;
    ... // Doing something
    if (condition_1 is true)
    {
        return v;
    }
    else
    {
        return VeryVeryVeryLongTypeName();
    }
    ... // Doing something
    if (condition_2 is true)
    {
        return v;
    }
    else
    {
        return VeryVeryVeryLongTypeName();
    }    
}

我认为return VeryVeryVeryLongTypeName();陈述非常乏味和丑陋,所以,我的问题是:

如何优雅地返回默认初始化的对象?

或者换句话说:

在C++标准中添加一个功能以使以下声明合法是一个好主意吗?

return default; // instead of return VeryVeryVeryLongTypeName();

这要简洁得多:

   return {};

您可以使用此类,其实例将自动隐式转换为所需类型的实例。即使默认构造函数标记为 explicit 或者您仍在使用 C++03,这也应该有效。对于C++11,公认的答案是简洁和更好的。

const struct default_t
{
     template<typename T>
     operator T() const {   return T{}; }
}default_{};

并将其用作:

VeryVeryVeryLongTypeName f()
{
     //...
     return default_;
}
WithExplicitConstructor_VeryVeryVeryLongTypeName g()
{
     //...
     return default_;
}

在线演示。

您可以在任何地方使用此解决方案,即使在模板中也是如此:

template<typename T>
typename father::template daughter<T>::grand_son_type h()
{
     //...
     return default_;
}

希望有帮助。

typedef怎么样?

class VeryVeryVeryLongTypeName;
typedef class VeryVeryVeryLongTypeName S;

然后使用S.

这里

正如其他人指出的那样,您可以依赖定义类型别名。在 C++11 中,您可以使用符号

using SnappyName = VeryVeryVeryLongTypeName;

然后在您想要的任何位置使用SnappyName

请记住,您需要回到您的代码,例如六个月后。使用一种方法可以帮助您(或您的合作者)明确理解您的意思。请记住:代码只写一次,读很多次。代码是为了以后的可读性,而不是为了节省击键。

您会收到问题的解决方案,但您应该注意一些事情。您编写函数的方式可以防止像NVRO那样的复制逃避。

该标准授权编译器从临时中跳过无用的副本,但它存在一些准则来匹配条件以实现优化。

在函数体中,您必须返回相同的同名 objet 而不返回任何其他内容,或者始终返回对象构造。将两者混合在一起,您将失去非常有价值的优化。