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

时间:2013-09-14 06:06:33

标签: c++ c++11 return default-value default-constructor

我有一个如下课程:

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();

5 个答案:

答案 0 :(得分:17)

这非常简洁:

   return {};

答案 1 :(得分:9)

您可以使用此类,其实例将自动隐式转换为所需类型的实例。即使默认构造函数标记为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_;
}

Online Demo

即使在模板中,您也可以使用此解决方案无处不在

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

希望有所帮助。

答案 2 :(得分:2)

typedef怎么样?

class VeryVeryVeryLongTypeName;
typedef class VeryVeryVeryLongTypeName S;

然后使用S

参见 HERE

答案 3 :(得分:2)

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

using SnappyName = VeryVeryVeryLongTypeName;

然后在任意位置使用SnappyName

请记住,从现在起六个月后,您需要回到您的代码中。使用一种方法可以帮助您(或您的合作者)明确地理解您的意思。请记住:代码只写一次并多次读取。代码用于以后的可读性,而不是目前的按键节省。

答案 4 :(得分:0)

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

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

在函数体中,您必须返回相同的命名对象,而不是其他任何东西,或者始终返回对象构造。混合这两者,你就失去了非常有价值的优化。