【发布时间】:2010-12-11 18:20:27
【问题描述】:
有什么区别
(type)value
和
type(value)
在 C++ 中?
【问题讨论】:
-
尚未提及的东西:
(type)value;和type(value);是不同的——后者定义了一个名为value的变量。
标签: c++ type-conversion casting
有什么区别
(type)value
和
type(value)
在 C++ 中?
【问题讨论】:
(type)value; 和 type(value); 是不同的——后者定义了一个名为 value 的变量。
标签: c++ type-conversion casting
没有区别;根据标准(§5.2.3):
一个简单类型说明符(7.1.5)后跟一个带括号的表达式列表构造一个给定表达式列表的指定类型的值。如果表达式列表是单个表达式,则类型转换表达式等效于(在定义上,并且如果在含义上定义)对应的强制转换表达式(5.4)。
由于问题指定了type(value)和(type)value之间的区别,所以绝对没有区别。
当且仅当您处理以逗号分隔的 list 值时,才会有区别。在这种情况下:
如果表达式列表指定了多个值,则类型应为具有适当声明的构造函数(8.5、12.1)的类,并且表达式 T(x1, x2, ...) 在效果上等同于声明 T t (x1, x2, ...);对于某些发明的临时变量 t,其结果是将 t 的值作为右值。
正如 Troubadour 所指出的,type(value) 版本根本无法编译某些类型的名称。例如:
char *a = (char *)string;
会编译,但是:
char *a = char *(string);
不会。但是,具有不同名称的相同类型(例如,使用 typedef 创建)可以工作:
typedef char *char_ptr;
char *a = char_ptr(string);
【讨论】:
type,而不是关于type*。它仍然适用于所有类型,因为制作合适的 typedef 将使 type 表示 char*。
char* 和identity<char*>::type(对于像boost::mpl::identity 这样的模板)和type 当type 被定义为char* 时都表示相同的类型。这个问题的措辞是type 应该表示一个类型(显然)。 type 在语法上是一个简单类型说明符,但 char* 不是。这是一个type-id,您可以将其作为模板参数传递。另外,请不要侮辱别人,说他们写的是“废话”。
char* 表示的类型 - 如果你 typedef 或者你写成 identity<char*>::type(value)
没有区别; C++ 标准(1998 和 2003 版)对这一点很清楚。试试下面的程序,确保你使用的是兼容的编译器,比如http://comeaucomputing.com/tryitout/的免费预览版。
#include <cstdlib>
#include <string>
int main() {
int('A'); (int) 'A'; // obvious
(std::string) "abc"; // not so obvious
unsigned(a_var) = 3; // see note below
(long const&) a_var; // const or refs, which T(v) can't do
return EXIT_SUCCESS;
}
注意:unsigned(a_var) 是不同的,但确实显示了这些确切标记可能意味着其他东西的一种方式。它声明了一个名为a_var 的无符号类型的变量,并且根本不是强制转换。 (如果您熟悉指向函数或数组的指针,请考虑如何在 p 周围使用括号,类型为 void (*pf)() 或 int (*pa)[42]。)
(产生警告是因为这些语句不使用该值,并且在实际程序中这几乎可以肯定是一个错误,但一切仍然有效。我只是不忍心在完成所有内容后更改它上。)
【讨论】:
两者都是强制类型转换时没有区别,但有时 'type(value)' 不是强制类型转换。
这是标准草案 N3242 第 8.2.1 节中的一个示例:
struct S
{
S(int);
};
void foo(double a)
{
S w( int(a) ); // function declaration
S y( (int)a ); // object declaration
}
在这种情况下,'int(a)' 不是强制转换,因为 'a' 不是一个值,它是一个被冗余括号括起来的参数名称。文件指出
由函数样式之间的相似性引起的歧义 cast 和 6.8 中提到的声明也可以出现在上下文中 的声明。在这种情况下,选择是在一个函数之间 在参数周围带有一组冗余括号的声明 名称和具有函数样式转换的对象声明作为 初始化器。正如 6.8 中提到的歧义一样, 决议是考虑任何可能是 声明一个声明。
【讨论】:
在 c 中没有 type (value),而在 c/c++ 中,type (value) 和 (type) value 都是允许的。
【讨论】:
为了说明你在 C++ 中的选择(只有一个有安全检查)
#include<boost/numeric/conversion/cast.hpp>
using std::cout;
using std::endl;
int main(){
float smallf = 100.1;
cout << (int)smallf << endl; // outputs 100 // c cast
cout << int(smallf) << endl; // outputs 100 // c++ constructor = c cast
cout << static_cast<int>(smallf) << endl; // outputs 100
// cout << static_cast<int&>(smallf) << endl; // not allowed
cout << reinterpret_cast<int&>(smallf) << endl; // outputs 1120416563
cout << boost::numeric_cast<int>(smallf) << endl; // outputs 100
float bigf = 1.23e12;
cout << (int)bigf << endl; // outputs -2147483648
cout << int(bigf) << endl; // outputs -2147483648
cout << static_cast<int>(bigf) << endl; // outputs -2147483648
// cout << static_cast<int&>(bigf) << endl; // not allowed
cout << reinterpret_cast<int&>(bigf) << endl; // outputs 1401893083
cout << boost::numeric_cast<int>(bigf) << endl; // throws bad numeric conversion
}
【讨论】: