在c++中,我们可以用{}进行C型铸造吗?

时间:2022-05-28 22:29:07

While I have been reading about datatype conversion, I saw this example:

当我阅读有关数据类型转换的文章时,我看到了这个例子:

void intval()
{
    for (char c; cin >> c; )
    cout << "the value of '" << c << "' is " << int{c} << '\n';
}

I know that we can cast using:

我知道我们可以使用:

  1. int(c)
  2. int(c)
  3. (int) c
  4. (int)c
  5. static_cast<int>(c)
  6. static_cast < int >(c)

My questions:

我的问题:

Q1: Is int{c} another way of casting data types?

Q1: int{c}是另一种类型的数据类型吗?

Q2: After some research on the net, I know that C++ casting is different and it have the compiler check the casting possibility at the compile time, but what are the differences between 1 and 2? And how int{c} is different if it is just another casting way?

问题2:通过对网络的一些研究,我知道c++的铸造是不同的,它让编译器在编译时检查铸造的可能性,但是1和2之间有什么区别呢?如果它只是另一种浇铸方式,它又有什么不同呢?

Q3: Are there any other ways to explicitly convert/cast?

Q3:有没有其他的方式可以显式转换/转换?

3 个解决方案

#1


8  

Is int{c} another way of casting data types?

int{c}是转换数据类型的另一种方式吗?

Yes. T{value} creates a temporary of type T that is direct-list-initialized with the specified braced-init-list. This cast does have an advantage over T(value) in that T{value} can be used to create a temporary array. That would be done like

是的。{value}创建了一个T类型的临时表,它是直接用指定的括号内列表初始化的。与T(value)相比,这个类型转换确实有一个优势,可以使用T{value}创建一个临时数组。可以这样做

int main() {
    using int_array = int[5];
    for( auto e : int_array{1,2,3,4,5})
        std::cout << e;
}

It also comes with the caveat that a narrowing conversion is a error

它还警告说,收缩转换是错误的

int main() {
    int(10000000000ll);  // warning only, still compiles
    int{10000000000ll};  // hard error mandated by the standard
}

After some research on the net, I know that C++ casting is different and it have the compiler check the casting possibility at the compile time, but what are the differences between 1 and 2?

经过对网络的一些研究,我知道c++的铸造是不同的,它让编译器在编译时检查浇注的可能性,但是1和2之间的区别是什么?

The big difference between T(value) and (T)value is that in T(value), T must be a single word. For example

T(value)和(T)值的最大区别在于T(值)中,T必须是一个单词。例如

int main() {
    unsigned int(10000000); // error
    (unsigned int)10000000; // compiles
}

Q3: Are there any other ways to explicitly convert/cast?

Q3:有没有其他的方式可以显式转换/转换?

Well in C++ they want you to use the C++ casts which are static_cast, reinterpret_cast, dynamic_cast, and const_cast. Those are preferred over c style cast as a c style cast will do all of those where the C++ versions have certain limitations and come with certain guarantees.

在c++中,他们希望您使用的c++类型转换为static_cast、reviewt_cast、dynamic_cast和const_cast。与c风格相比,这些是首选的,因为c风格的转换将完成所有那些c++版本有一定限制和有一定保证的地方。

#2


6  

int(c) is the the C++ version of the C-style cast (int)c. It first attempts a const_cast<int>(c), then (failing that) a static_cast<int>(c) followed by reinterpret_cast.

int(c)是c风格的cast (int)c的c++版本。它首先尝试一个const_cast (c),然后(如果失败)一个static_cast (c),然后是reinterpret_cast。

int{c} is a slightly different cattle of fish. Strictly, this is list initialization and has more stringent rules. In particular, narrowing conversions are not allowed, i.e.

这是一种稍微不同的鱼类。严格地说,这是列表初始化,并且有更严格的规则。特别是,不允许窄化转换,即。

int x;
char s{x};  // error

Therefore, it is recommended to use this (rather than casts) unless you know that narrowing conversions are acceptable.

因此,建议使用这个(而不是强制类型转换),除非您知道窄化转换是可以接受的。

For other than builtin types, there is, in addition to the casts mentioned above, also dynamic_cast.

除了内置类型之外,除了上面提到的类型转换之外,还有dynamic_cast。

#3


3  

Q1: Yes. It is almost the same as a functional style cast (int(c)), and works because of c++11's uniform initialization. However brace initialization does have a few caveats, for example narrowing conversions (like long l = 5; char c{l};) will generate a warning.

Q1:是的。它几乎与函数式类型转换(int(c))相同,并且由于c++11的统一初始化而起作用。但是,括号初始化有一些注意事项,例如缩小转换(比如长l = 5;char c{l};)将生成一个警告。

Q2: 1 and 2 are equivalent, although there are some situations where one works and not the other.

Q2: 1和2是等价的,尽管在某些情况下一个是有效的,另一个不是。

// long long(c); // Breaks unless you make a typedef for 'long long'
(long long)c;    // Works fine

template <class In, class Out>
Out convert(const In& in) {
    // return (Out)in; // Only works if 'In' is a primitive type
    return Out(in);    // Works regardless of the type of 'In' (assuming an appropriate constructor exists)
}

Q3: The only example of C++-style casting that you mention is static_cast. There are other C++ casts as well:

Q3:您提到的c++风格的强制转换的惟一示例是static_cast。还有其他的c++类型转换:

  • dynamic_cast
  • dynamic_cast
  • reinterpret_cast
  • reinterpret_cast
  • const_cast
  • const_cast

#1


8  

Is int{c} another way of casting data types?

int{c}是转换数据类型的另一种方式吗?

Yes. T{value} creates a temporary of type T that is direct-list-initialized with the specified braced-init-list. This cast does have an advantage over T(value) in that T{value} can be used to create a temporary array. That would be done like

是的。{value}创建了一个T类型的临时表,它是直接用指定的括号内列表初始化的。与T(value)相比,这个类型转换确实有一个优势,可以使用T{value}创建一个临时数组。可以这样做

int main() {
    using int_array = int[5];
    for( auto e : int_array{1,2,3,4,5})
        std::cout << e;
}

It also comes with the caveat that a narrowing conversion is a error

它还警告说,收缩转换是错误的

int main() {
    int(10000000000ll);  // warning only, still compiles
    int{10000000000ll};  // hard error mandated by the standard
}

After some research on the net, I know that C++ casting is different and it have the compiler check the casting possibility at the compile time, but what are the differences between 1 and 2?

经过对网络的一些研究,我知道c++的铸造是不同的,它让编译器在编译时检查浇注的可能性,但是1和2之间的区别是什么?

The big difference between T(value) and (T)value is that in T(value), T must be a single word. For example

T(value)和(T)值的最大区别在于T(值)中,T必须是一个单词。例如

int main() {
    unsigned int(10000000); // error
    (unsigned int)10000000; // compiles
}

Q3: Are there any other ways to explicitly convert/cast?

Q3:有没有其他的方式可以显式转换/转换?

Well in C++ they want you to use the C++ casts which are static_cast, reinterpret_cast, dynamic_cast, and const_cast. Those are preferred over c style cast as a c style cast will do all of those where the C++ versions have certain limitations and come with certain guarantees.

在c++中,他们希望您使用的c++类型转换为static_cast、reviewt_cast、dynamic_cast和const_cast。与c风格相比,这些是首选的,因为c风格的转换将完成所有那些c++版本有一定限制和有一定保证的地方。

#2


6  

int(c) is the the C++ version of the C-style cast (int)c. It first attempts a const_cast<int>(c), then (failing that) a static_cast<int>(c) followed by reinterpret_cast.

int(c)是c风格的cast (int)c的c++版本。它首先尝试一个const_cast (c),然后(如果失败)一个static_cast (c),然后是reinterpret_cast。

int{c} is a slightly different cattle of fish. Strictly, this is list initialization and has more stringent rules. In particular, narrowing conversions are not allowed, i.e.

这是一种稍微不同的鱼类。严格地说,这是列表初始化,并且有更严格的规则。特别是,不允许窄化转换,即。

int x;
char s{x};  // error

Therefore, it is recommended to use this (rather than casts) unless you know that narrowing conversions are acceptable.

因此,建议使用这个(而不是强制类型转换),除非您知道窄化转换是可以接受的。

For other than builtin types, there is, in addition to the casts mentioned above, also dynamic_cast.

除了内置类型之外,除了上面提到的类型转换之外,还有dynamic_cast。

#3


3  

Q1: Yes. It is almost the same as a functional style cast (int(c)), and works because of c++11's uniform initialization. However brace initialization does have a few caveats, for example narrowing conversions (like long l = 5; char c{l};) will generate a warning.

Q1:是的。它几乎与函数式类型转换(int(c))相同,并且由于c++11的统一初始化而起作用。但是,括号初始化有一些注意事项,例如缩小转换(比如长l = 5;char c{l};)将生成一个警告。

Q2: 1 and 2 are equivalent, although there are some situations where one works and not the other.

Q2: 1和2是等价的,尽管在某些情况下一个是有效的,另一个不是。

// long long(c); // Breaks unless you make a typedef for 'long long'
(long long)c;    // Works fine

template <class In, class Out>
Out convert(const In& in) {
    // return (Out)in; // Only works if 'In' is a primitive type
    return Out(in);    // Works regardless of the type of 'In' (assuming an appropriate constructor exists)
}

Q3: The only example of C++-style casting that you mention is static_cast. There are other C++ casts as well:

Q3:您提到的c++风格的强制转换的惟一示例是static_cast。还有其他的c++类型转换:

  • dynamic_cast
  • dynamic_cast
  • reinterpret_cast
  • reinterpret_cast
  • const_cast
  • const_cast