2017-08-04 52 views
3

我了解到,在C++中,功能样式转换与构造

typedef foo* mytype; 

(mytype) a  // C-style cast 

mytype(a)   // function-style cast 

做同样的事情。

但我注意到函数式转换与构造函数共享相同的语法。 是不是有不明确的情况下,我们不知道它是一个演员或建设者?

char s [] = "Hello"; 
std::string s2 = std::string(s);  // here it's a constructor but why wouldn't it be ... 
std::string s3 = (std::string) s; // ... interpreted as a function-style cast? 
+2

实际上,在您显示的示例中*两个*个案都会调用一个'std :: string'构造函数。 *相同*构造函数。 –

+0

注意:在C++中,你通常应该更喜欢明确的转换static_cast,reinterpret_cast,const_cast,dynamic_cast,static_pointer_cast,reinterpret_pointer_cast,const_pointer_cast和dynamic_pointer_cast(以及move& '前锋' - 是的,他们*只是在C风格演员阵容*上)。他们更容易在代码中搜索,对于意图和安全性更加明确(例如,最糟糕的C风格演员阵容是生成'reinterpret_cast',后面跟着'const_cast')。 –

回答

10

句法上,它是总是一个演员。该演员阵容可能恰好称为构造函数:

char s [] = "Hello"; 
// Function-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s2 = std::string(s); 
// C-style cast; internally calls std::basic_string<char>::basic_string(char const*, Allocator) 
std::string s3 = (std::string) s; 
0

编译器知道。当两种情况都有一个时,它会调用构造函数。

1

转换是初始化的一种形式。当一个类型可以隐式转换为另一个类型时,函数类型转换是一种直接初始化的形式。编译器知道哪些类型是可转换的。

只要有东西转换为类类型,就会使用目标类型的转换构造函数或源类型的转换运算符。在你的例子中,两个cast都调用默认的构造函数。

+0

谢谢。好的,编译器知道,但我怎么知道哪些情况可以通过构造函数转换,或者只是通过改变类型而不改变值(如c风格转换)? – Basj

+0

@Basj'我怎么能知道哪些情况是可转换的?您可以使用'std :: is_convertible'来请求编译器,或者您可以阅读该类的定义(以及源对象的类的定义,如果适用),以查看类具有适当的转换构造函数(或源对象具有适当的转换运算符)。转换为类类型始终是对构造函数的调用。通过查看它的定义,你可以发现一个类型是否是一个类。 – user2079303

+0

“只要有东西被转换为类类型,就调用构造函数。” - 不正确。转换操作符可能会被调用。这并不一定会调用构造函数(它通常会,但它可能会通过引用返回缓存的对象)。 –