C++11-清除返回值语法和decltype关键字



从这里开始阅读,这段C++11代码对我来说似乎很奇怪:

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )
{
    auto val = builder.makeObject();
    // do stuff with val
    return val;
}

我有几个问题:

1( decltype(builder.makeObject(((是否在执行实际调用之前再调用一次makeObject函数?

2( 如果不是,并且在编译时一切都是已知的(所以它是一个增强的宏(,为什么下面的语法无效,我需要新的返回值语法?

//WRONG    
template <typename Builder>
    decltype( builder.makeObject() )
    makeAndProcessObject (const Builder& builder)
    {
        auto val = builder.makeObject();
        // do stuff with val
        return val;
    }

[奖励问题-回答后获得+1分]3( 在这个问题中,一个人问为什么他的代码没有编译,答案是成员函数makeObject缺少一个"const"说明符。我得到了答案,但不知道为什么需要const。

以下申报的内容

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )

如果const Builder&对象引用具有const makeObject还是非常量makeObject?decltype(builder.makeObject(((部分必须只找出函数的返回类型,它不应该关心函数是否修改了作为参数传递的对象!

通常,C++中的东西在声明之后才可用。在您的示例中,您试图在声明生成器之前使用它:

template <typename Builder>
    decltype( builder.makeObject() ) // using builder here
    makeAndProcessObject (const Builder& builder) // but builder isn't declared until here
    {
        auto val = builder.makeObject();
        // do stuff with val
        return val;
    }

添加函数返回类型的新语法是为了解决这个问题。

template <typename Builder>
auto // dummy return type, meaning we will give it later
makeAndProcessObject (const Builder& builder)  // declaring builder here
-> decltype( builder.makeObject() ) // using builder here -- no problem.
{
    auto val = builder.makeObject();
    // do stuff with val
    return val;
}

至于你的额外问题:对于语言来说,说你必须给decltype一个有效的表达式要简单得多,而不是有另一组关于哪些参数对decltype有效的规则。

  1. 没有。decltype创建一个未赋值的上下文,就像sizeof一样。编译器只查看类型信息,而不查看其他信息。

  2. 不能在前导返回类型中使用参数。

    decltype( builder.makeObject() ) makeAndProcessObject (const Builder& builder)
    

由于CCD_ 3是未知标识符。这就是创建尾随返回类型的原因。

  • 在未评估的上下文中,类型信息很重要。并且this参数是否为const是类型信息的一部分。如果decltype不进行过载解析,它将毫无用处。如果您从未见过基于成员函数的const的重载,那么这可能没有意义,但可能有两个具有相同名称和参数的函数,一个用于对象的const视图,另一个用于非const。返回类型可以不同(实际上,它们通常因const而不同(

答案:

1( 不是。decltype只在编译时计算表达式的类型,在运行时不计算表达式的值。因此,decltype被称为"未评估的上下文",因为它是sizeofnoexcept

2( 请注意,在此声明中

template <typename Builder>
decltype( builder.makeObject() )
makeAndProcessObject (const Builder& builder)

编译器在看到声明const Builder& builder之前先看到builder,而对于已接受的声明,在确定返回类型时,编译器已经解析了所需的所有信息。auto关键字告诉编译器在稍后有更多信息可用时,将给出返回类型。

3( 问题不在于申报

template <typename Builder>
auto
makeAndProcessObject (const Builder& builder) -> decltype( builder.makeObject() )

它实际上与功能体有关。更准确地说,以下行:

auto val = builder.makeObject();

由于builderconst Builder&,因此只能在builder上调用const方法,而且最初makeObject()不是其中之一。然后用const的方法解决了这个问题。

更新:阅读Ben Voigt的答案后。与我上面所说的相反,声明中也存在问题,因为它使用了decltype(builder.makeObject()),并且我在函数体中使用的参数也适用于此。

最新更新