Ale*_*lis 4 c++ standards casting
根据标准(§5.2.11),const_cast抛弃了cv-qualifiers(const或volatile).
这是一个简单的例子.首先,您声明两个函数采用指针和引用:
class Bar { ... };
void foo_ptr(Bar*);
void foo_ref(Bar&);
Run Code Online (Sandbox Code Playgroud)
然后你创建一个引用到const:
Bar b;
const Bar& cb = b;
Run Code Online (Sandbox Code Playgroud)
然后你可以使用适当的const_cast调用任一函数:
foo_ptr(const_cast<Bar*>(&cb));
foo_ref(const_cast<Bar&>(cb));
Run Code Online (Sandbox Code Playgroud)
这是我的问题:由于const_cast无法完成其他演员的设计,你投射的内容不是很明显吗?换句话说,为什么语言不允许我简单地说:
foo_ptr(const_cast<>(&cb));
foo_ref(const_cast<>(cb));
Run Code Online (Sandbox Code Playgroud)
我只能想到以下两个原因:
a)当我尝试做一些疯狂的事情时,编译器应该阻止我,例如:
foo_ptr(const_cast<int*>(&cb));
foo_ref(const_cast<int&>(cb));
Run Code Online (Sandbox Code Playgroud)
并强迫我明确说明我正在施放的类型,然后可以防止行为不端.我发现这个(假设的)解释很弱,因为如果语言偏好允许我写下错误只是为了让编译器纠正我,这将是奇怪的.
b)如果变量既是const又是volatile,则可能存在歧义.在这种情况下,编译器无法告诉我是否试图抛弃一个或另一个(或两者).
这是为什么,还是有其他原因?
const_cast可用于添加或删除 const和volatile限定符.因此,如果允许这样的语法,则以下所有内容都是合法的目标类型const_cast<>(&cb):
Bar*                 (1)
const Bar*           (2)
volatile Bar*        (3)
const volatile Bar*  (4)
Run Code Online (Sandbox Code Playgroud)
你打算(1).  (2)通常是愚蠢的,但可以想象它可能出现在某个地方,也许在一些模板代码中.  确实存在问题:(3)和(4):你可以删除const资格并添加volatile资格证书.
你可以替换现有的const_cast具有一对铸件,const_cast和volatile_cast,和禁止的情况下(2) ; 然后你可以使用其中任何一个没有目标类型.但是,知道转换表达式的类型会更加困难.要了解强制转换表达式是否添加或删除了限定条件,您必须知道源表达式的类型.
没有理由你不能使用函数模板来获得你想要的东西:
template <typename T>
T* remove_const(const T* p) {
    return const_cast<T*>(p);
}
Run Code Online (Sandbox Code Playgroud)
你可以很容易地编写类似的功能remove_volatile和add_const和add_volatile,这两者都是隐含的.
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           801 次  |  
        
|   最近记录:  |