简体   繁体   English

C ++函数式转换的目的究竟是什么?

[英]What exactly is or was the purpose of C++ function-style casts?

I am talking about "type(value)"-style casts. 我说的是“类型(值)” - 样式演员。 The books I have read pass over them quickly, saying only that they are semantically equivalent to C-style casts, "(type) value", and that they should be avoided. 我读过的书很快就传递过来,只说它们在语义上等同于C风格的演员表,“(类型)值”,并且应该避免它们。 If they mean the same thing an old-style cast does, why were they ever added to the language? 如果他们的意思与旧式演员的意思相同,他们为什么要加入这种语言呢? Also, because declarations can contain superfluous parentheses, this code: "T x(T(y));" 此外,因为声明可以包含多余的括号,所以此代码为:“T x(T(y));” doesn't do what someone intending to use the function-style casts would expect; 没有人打算使用函数式演员所期望的; it declares a function named x accepting a T and returning a T rather than constructing a T variable named x by casting y to a T. 它声明了一个名为x的函数,它接受一个T并返回一个T而不是通过将y转换为T来构造一个名为x的T变量。

Were they a mistake in the design of the language? 他们在语言设计上是个错误吗?

Function style casts bring consistency to primitive and user defined types. 函数样式转换为原始类型和用户定义类型带来了一致性。 This is very useful when defining templates. 这在定义模板时非常有用。 For example, take this very silly example: 例如,采取这个非常愚蠢的例子:

template<typename T, typename U>
T silly_cast(U const &u) {
  return T(u);
}

My silly_cast function will work for primitive types, because it's a function-style cast. 我的silly_cast函数适用于原始类型,因为它是一个函数式转换。 It will also work for user defined types, so long as class T has a single argument constructor that takes a U or U const &. 它也适用于用户定义的类型,只要类T有一个带有U或U const&的参数构造函数。

template<typename T, typename U>
T silly_cast(U const &u) {
    return T(u);
}

class Foo {};
class Bar {
public:
    Bar(Foo const&) {};
};

int main() {
    long lg = 1L;
    Foo f;
    int v = silly_cast<int>(lg);
    Bar b = silly_cast<Bar>(f);
}

The purpose of them is so you could pass more than one argument to a class' constructor: 它们的目的是让你可以将多个参数传递给类的构造函数:

T(a1, a2); // call 2-argument constructor
(T)(a1, a2); // would only pass a2.

There is no mechanism that the (T) expr style cast would be able to pass multiple arguments, so a new form of conversion was needed. 没有(T) expr样式转换能够传递多个参数的机制,因此需要一种新的转换形式。 It's natural to define (T) expr as a degenerate case of T(expr) . (T) expr定义为T(expr)的退化情况是很自然的。

Contrary to what some people here say, (T) expr works exactly like T(expr) , so it will work just fine with class types too. 与这里的一些人所说的相反, (T) expr工作方式与T(expr)完全相同,因此它也适用于类类型。

It is somewhat easier to parse the function-style casts in a language where parentheses are already heavily (over-)used. 在一个已经大量(过度使用)括号的语言中解析函数式转换更容易一些。

Were they a mistake? 他们是个错误吗? Possibly - but only to the extent that they were unable to completely supersede the C-style casts, and therefore provided a Perl-like "there's more than one way to do it" mechanism for casting. 可能 - 但只是在他们无法完全取代C风格的演员表的程度上,因此提供了类似Perl的“有不止一种方法去做”演员的机制。 With the explicit and distinctive modern casts: 凭借明确而独特的现代演员阵容:

dynamic_cast<type>(value);
reinterpret_cast<type>(value);
static_cast<type>(value);
const_cast<type>(value);

there is no reason to use the C-style casts any more, and less reason to use function-style casts. 没有理由再使用C风格的强制转换,也没有理由使用函数式转换。

C-style casts should not be used. 不应使用C风格的演员表。

Function-style casts should be used, especially when the target type is a class name (or class template specialization). 应该使用函数式转换,尤其是当目标类型是类名(或类模板特化)时。 They fit the pattern of apparent constructor calls in the case with one argument. 在一个参数的情况下,它们符合明显构造函数调用的模式。

MyClass( expr );   // Creates temporary, initialized like MyClass obj( expr );
MyClass( e1, e2 ); // Similar, and no other way to write this.
int( expr );       // Function-style cast.

AFAIK function-style casts are an extension to native types of the usual syntax of temporary creation for classes: as long as you can create a temporary object inside an expression using the syntax ClassName(parameters) , there's no reason why you shouldn't do that with native types. AFAIK函数样式转换是对类的临时创建的常规语法的本机类型的扩展:只要您可以使用语法ClassName(parameters)在表达式内创建临时对象,就没有理由不这样做与原生类型。 edit Notice that, as @steve said, this is very useful in templates 编辑 请注意,正如@steve所说,这在模板中非常有用

Notice that one-parameter constructors in C++ are often somehow "felt" as conversion facilities, see for example the syntax ( conversion constructor ) that allows you to initialize a new object using an equal sign followed by a value 请注意,C ++中的单参数构造函数通常以某种方式“感觉”为转换工具,例如,请参阅允许您使用等号后跟值初始化新对象的语法( 转换构造函数

ClassName MyObject = 3;

which actually means 这实际上意味着

ClassName MyObject(3);

and (presumably) calls the one- int -parameter constructor of ClassName. 和(推测)调用ClassName的one- int -parameter构造函数。

By the way, here 'sa nice page about function-style casts. 顺便说一句, 是一个关于函数式转换的好页面。

What book was this??? 这本书是什么? It's the C-style casts which are generally thought to be a bad idea. 这是C风格的演员,通常被认为是一个坏主意。 Most modern C++ code looks like this (when a cast is needed) 大多数现代C ++代码都是这样的(当需要强制转换时)

x = sometype( y );

rather than 而不是

x = (sometype) y;

Apart from anything else, the former syntax looks much more like a constructor call, which in most cases it probably is, though the two forms are actually semantically identical. 除了其他任何东西,前一种语法看起来更像是构造函数调用,在大多数情况下它可能是,尽管这两种形式实际上在语义上是相同的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM