8

我有一个像下面这样的课程:

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

5 回答 5

17

这是非常简洁的:

   return {};
于 2013-09-14T06:10:16.567 回答
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_;
}

在线演示

您可以在任何地方使用此解决方案,甚至在模板中:

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

希望有帮助。

于 2013-09-14T06:18:32.750 回答
2

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

using SnappyName = VeryVeryVeryLongTypeName;

然后SnappyName在任何你想使用的地方使用。

请记住,您将需要在六个月后返回您的代码。使用可以帮助您(或您的合作者)明确理解您的意思的方法。记住:代码写一次,读多次。代码用于以后的可读性,而不是当前的击键节省。

于 2013-09-14T06:36:54.233 回答
2

怎么样typedef

class VeryVeryVeryLongTypeName;
typedef class VeryVeryVeryLongTypeName S;

然后使用S.

这里

于 2013-09-14T06:14:21.937 回答
0

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

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

在函数体中,您必须要么返回同名的对象而不是其他任何东西,要么总是返回一个对象构造。将两者混合在一起,您就会失去非常有价值的优化。

于 2013-09-14T09:51:26.180 回答