【问题标题】:Is {1, 2} a value? If yes, what is its type? If no, why can it be assigned to an initializer list?{1, 2} 是一个值吗?如果是,它的类型是什么?如果不是,为什么可以将它分配给初始化列表?
【发布时间】:2013-09-18 19:56:02
【问题描述】:
#include <initializer_list>

using namespace std;

template<class T>
void f(initializer_list<T>)
{}

int main()
{
    typeid(1);           // OK
    typeid(int);         // OK
    typeid(decltype(1)); // OK

    f({1, 2}); // OK

    typeid({1, 2});           // error
    decltype({1, 2}) v;       // error
    typeid(decltype({1, 2})); // error
}

{1, 2} 是一个值吗?

如果是,为什么是 typeid({1, 2});不合法?

如果不是,为什么可以分配给一个initializer_list对象?

【问题讨论】:

  • Clang 3.4 说得很清楚。那些需要表达。
  • {1,2} 不是表达式。
  • 我认为标准仅/主要在对象的值上下文中使用术语。还有表达式的值类别(如右值和左值)。 {1,2} 既不是对象也不是表达式,因此我认为不能将其命名为
  • @DyP prvalues 是没有对象的定义值。一个对象是通过有一个地址来定义的,把它放在左值类别中。但是,是的,初始化列表只是形成您可能想要的值的说明。
  • @Potatoswatter “一个对象是通过一个地址来定义的”,这会使临时对象成为非对象。文字显然是非对象,但具有类型和值类别。我认为说它们也有价值并没有错。但也许,它们只是值?

标签: c++ c++11 types type-conversion initializer-list


【解决方案1】:

typeid 需要一个表达式

表格here

typeid 表达式是左值表达式,它引用多态类型const std::type_info 或从它派生的某种类型的静态对象。

语法:typeid(表达式)

检查表达式表达式

  • typeid 表达式计算 表达式,然后引用表示表达式动态类型的 std::type_info 对象。

  • 如果表达式不是多态类型的左值表达式,typeid 不会计算表达式,它标识的std::type_info 对象代表表达式的静态类型。

【讨论】:

  • 但是{ … } 不是一个表达式,所以你可以在任何值类别的东西之前停下来。
【解决方案2】:
  1. 不,它是一种没有内在价值的句法结构。它甚至不是(在语法上)一个表达式。但它可以用来初始化一个对象。

    typeid 运算符需要正确的表达式,但函数参数不需要。传递函数参数时,实际上是在初始化参数对象。

  2. initializer_list可以被这样的东西初始化。数组也可以通过花括号初始化器列表进行初始化。该列表用于初始化通过initializer_list访问的数组。

令人困惑的是,auto x = { 1, 2, 3 }; 导致 x 被声明为 std::initializer_list&lt; int &gt;。这是autodecltype 不同的特殊例外,并且已被提议弃用。持久化initializer_lists 没有什么好的用途。

【讨论】:

    猜你喜欢
    • 2018-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 2013-03-13
    • 2023-02-04
    • 2014-01-20
    相关资源
    最近更新 更多