为什么构造函数语法不能与“无符号int”类型一起使用?

时间:2021-06-24 22:29:11

Why is the following illegal in C++?

为什么以下内容在c++中是非法的?

auto x = unsigned int(0);

Whereas the following are all OK:

而下面这些都可以:

auto y = int(0);
auto z = unsigned(0);
auto w = float(0);

or in general:

或一般:

auto t = Type(... c-tor-args ...);

(with the exception of Type being unsigned int).

(除非类型为无符号整数)。

2 个解决方案

#1


32  

The syntax is Explicit type conversion (functional notation) here. According to the grammatical rule, it only works with simple type specifier or typedef specifier (i.e. a single-word type name).

这里的语法是显式类型转换(函数标记)。根据语法规则,它只适用于简单类型说明符或类型定义说明符(即单字类型名称)。

(emphasis mine)

(强调我的)

2) The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name: unsigned int(expression) or int*(expression) are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.

2)函数类型转换表达式由一个简单的类型说明符或一个typedef说明符(换句话说,一个单字类型名称:unsigned int(表达式)或int*(表达式)无效)组成,后面是一个括号中的表达式。这个强制转换表达式与相应的c样式强制转换表达式完全等价。

You can change it to c-style cast expression or static_cast, or use it with typedef specifier as @Jean-FrançoisFabre suggested.

您可以将它更改为c样式的cast表达式或static_cast,或者使用它与@Jean-FrancoisFabre建议的typedef说明符一起使用。

auto x1 = (unsigned int)(0);
auto x2 = static_cast<unsigned int>(0);

Quotes from the standard, $5.2.3/1 Explicit type conversion (functional notation) [expr.type.conv]

引用标准,$5.2.3/1显式类型转换(函数表示法)[exp .type.conv]

A simple-type-specifier ([dcl.type.simple]) or typename-specifier ([temp.res]) followed by a parenthesized optional expression-list or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer.

一个简单类型说明符([dcl.type.simple])或typenam -说明符([temp.res]),后面跟着一个括号内的可选表达式列表或一个括号内的列表(初始化器)构造给定初始化器的指定类型的值。

And $7.1.7.2/1 Simple type specifiers [dcl.type.simple]

$ 7.1.2 /1简单类型说明符[dcl.type.simple]

The simple type specifiers are

简单类型说明符是。

simple-type-specifier:
    nested-name-specifieropt type-name
    nested-name-specifier template simple-template-id
    nested-name-specifieropt template-name
    char
    char16_t
    char32_t
    wchar_t
    bool
    short
    int
    long
    signed
    unsigned
    float
    double
    void
    auto
    decltype-specifier
type-name:
    class-name
    enum-name
    typedef-name
    simple-template-id
decltype-specifier:
  decltype ( expression )
  decltype ( auto )

#2


20  

Because of parsing priority. The compiler is lost because int(0) is matched before unsigned int.

由于解析优先。编译器丢失,因为在无符号整型之前匹配int(0)。

You have to enclose your type in parentheses:

你必须把你的类型用括号括起来:

auto x = (unsigned int)(0);

or use a typedef:

或者使用类型定义:

typedef unsigned int uint;
auto x = uint(0);

#1


32  

The syntax is Explicit type conversion (functional notation) here. According to the grammatical rule, it only works with simple type specifier or typedef specifier (i.e. a single-word type name).

这里的语法是显式类型转换(函数标记)。根据语法规则,它只适用于简单类型说明符或类型定义说明符(即单字类型名称)。

(emphasis mine)

(强调我的)

2) The functional cast expression consists of a simple type specifier or a typedef specifier (in other words, a single-word type name: unsigned int(expression) or int*(expression) are not valid), followed by a single expression in parentheses. This cast expression is exactly equivalent to the corresponding C-style cast expression.

2)函数类型转换表达式由一个简单的类型说明符或一个typedef说明符(换句话说,一个单字类型名称:unsigned int(表达式)或int*(表达式)无效)组成,后面是一个括号中的表达式。这个强制转换表达式与相应的c样式强制转换表达式完全等价。

You can change it to c-style cast expression or static_cast, or use it with typedef specifier as @Jean-FrançoisFabre suggested.

您可以将它更改为c样式的cast表达式或static_cast,或者使用它与@Jean-FrancoisFabre建议的typedef说明符一起使用。

auto x1 = (unsigned int)(0);
auto x2 = static_cast<unsigned int>(0);

Quotes from the standard, $5.2.3/1 Explicit type conversion (functional notation) [expr.type.conv]

引用标准,$5.2.3/1显式类型转换(函数表示法)[exp .type.conv]

A simple-type-specifier ([dcl.type.simple]) or typename-specifier ([temp.res]) followed by a parenthesized optional expression-list or by a braced-init-list (the initializer) constructs a value of the specified type given the initializer.

一个简单类型说明符([dcl.type.simple])或typenam -说明符([temp.res]),后面跟着一个括号内的可选表达式列表或一个括号内的列表(初始化器)构造给定初始化器的指定类型的值。

And $7.1.7.2/1 Simple type specifiers [dcl.type.simple]

$ 7.1.2 /1简单类型说明符[dcl.type.simple]

The simple type specifiers are

简单类型说明符是。

simple-type-specifier:
    nested-name-specifieropt type-name
    nested-name-specifier template simple-template-id
    nested-name-specifieropt template-name
    char
    char16_t
    char32_t
    wchar_t
    bool
    short
    int
    long
    signed
    unsigned
    float
    double
    void
    auto
    decltype-specifier
type-name:
    class-name
    enum-name
    typedef-name
    simple-template-id
decltype-specifier:
  decltype ( expression )
  decltype ( auto )

#2


20  

Because of parsing priority. The compiler is lost because int(0) is matched before unsigned int.

由于解析优先。编译器丢失,因为在无符号整型之前匹配int(0)。

You have to enclose your type in parentheses:

你必须把你的类型用括号括起来:

auto x = (unsigned int)(0);

or use a typedef:

或者使用类型定义:

typedef unsigned int uint;
auto x = uint(0);