【问题标题】:decltype vs autodecltype 与自动
【发布时间】:2012-08-23 02:41:24
【问题描述】:

据我了解,decltypeauto 都会尝试找出某物的类型。

如果我们定义:

int foo () {
    return 34;
}

那么这两个声明都是合法的:

auto x = foo();
cout << x << endl;

decltype(foo()) y = 13;
cout << y << endl;

您能告诉我decltypeauto 之间的主要区别是什么吗?

【问题讨论】:

标签: c++ type-inference


【解决方案1】:

decltype 给出了传递给它的表达式的声明 类型。 auto 和模板类型推导一样。因此,例如,如果您有一个返回引用的函数,auto 仍将是一个值(您需要auto&amp; 来获取引用),但decltype 将完全是返回值的类型。

#include <iostream>
int global{};
int& foo()
{
   return global;
}

int main()
{
    decltype(foo()) a = foo(); //a is an `int&`
    auto b = foo(); //b is an `int`
    b = 2;

    std::cout << "a: " << a << '\n'; //prints "a: 0"
    std::cout << "b: " << b << '\n'; //prints "b: 2"

    std::cout << "---\n";
    decltype(foo()) c = foo(); //c is an `int&`
    c = 10;

    std::cout << "a: " << a << '\n'; //prints "a: 10"
    std::cout << "b: " << b << '\n'; //prints "b: 2"
    std::cout << "c: " << c << '\n'; //prints "c: 10"
 }

另请参阅 David Rodríguez 的回答,关于在哪些地方只有 autodecltype 之一是可能的。

【讨论】:

    【解决方案2】:

    auto(在它推断类型的上下文中)仅限于定义具有初始化程序的变量的类型。 decltype 是一个更广泛的构造,它会以额外信息为代价来推断表达式的类型。

    在可以使用auto 的情况下,它比decltype 更简洁,因为您不需要提供用于推断类型的表达式。

    auto x = foo();                           // more concise than `decltype(foo()) x`
    std::vector<decltype(foo())> v{ foo() };  // cannot use `auto`
    

    关键字auto 也用于完全不相关的上下文中,当为函数使用尾随返回类型时:

    auto foo() -> int;
    

    auto 只是一个领导者,因此编译器知道这是一个带有尾随返回类型的声明。虽然上面的示例可以轻松转换为旧样式,但在泛型编程中它很有用:

    template <typename T, typename U>
    auto sum( T t, U u ) -> decltype(t+u)
    

    请注意,在这种情况下,auto 不能用于定义返回类型。

    【讨论】:

      【解决方案3】:

      修改@Mankarse的示例代码,我认为更好的自爆:

      #include <iostream>
      int global = 0;
      int& foo()
      {
         return global;
      }
      
      int main()
      {
          decltype(foo()) a = foo(); //a is an `int&`
          auto b = foo(); //b is an `int`
          b = 2;
      
          std::cout << "a: " << a << '\n'; //prints "a: 0"
          std::cout << "b: " << b << '\n'; //prints "b: 2"
          std::cout << "global: " << global << '\n'; //prints "global: 0"
      
          std::cout << "---\n";
      
          //a is an `int&`
          a = 10;
      
          std::cout << "a: " << a << '\n'; //prints "a: 10"
          std::cout << "b: " << b << '\n'; //prints "b: 2"
          std::cout << "global: " << global << '\n'; //prints "global: 10"
      
          return 0;
      
      }
      

      【讨论】:

        【解决方案4】:

        通常,如果您需要为要初始化的变量指定类型,请使用 autodecltype 更适合用于非变量类型(如返回类型)的类型。

        【讨论】:

          【解决方案5】:

          我认为 auto 是一个纯粹的简化功能,而 decltype 的主要目的是 在基础库中启用复杂的元编程。然而,它们非常接近 从语言技术的使用角度来看是相关的。

          来自HOPL20 4.2.1,Bjarne Stroustrup。

          【讨论】:

            猜你喜欢
            • 2013-07-10
            • 1970-01-01
            • 1970-01-01
            • 2014-10-19
            • 2014-10-08
            • 2023-03-12
            • 2019-08-10
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多