C++ 从模板函数内部的类型中删除常量
那么:C++ 从模板函数内部的类型中删除常量,c++,templates,constants,C++,Templates,Constants,那么: const int *p; Remove(p); // error related to `foo()` 模板 结构非标准{ 静态T&value(T&value){返回值;} }; 样板 结构非标准{ 静态T&value(T常量和值){返回常量转换(值);} }; 按如下方式使用: template <typename T> struct nonconst { static T& value(T& value) { return value; }
const int *p;
Remove(p); // error related to `foo()`
模板
结构非标准{
静态T&value(T&value){返回值;}
};
样板
结构非标准{
静态T&value(T常量和值){返回常量转换(值);}
};
按如下方式使用:
template <typename T>
struct nonconst {
static T& value(T& value) { return value; }
};
template <typename T>
struct nonconst<T const> {
static T& value(T const& value) { return const_cast<T&>(value); }
};
模板
脱空(T*p){
foo(&nonst::value(*p));
}
(或者将模板进一步专门用于(非)常量指针。)如何:
const int *p;
Remove(p); // error related to `foo()`
模板
结构非标准{
静态T&value(T&value){返回值;}
};
样板
结构非标准{
静态T&value(T常量和值){返回常量转换(值);}
};
按如下方式使用:
template <typename T>
struct nonconst {
static T& value(T& value) { return value; }
};
template <typename T>
struct nonconst<T const> {
static T& value(T const& value) { return const_cast<T&>(value); }
};
模板
脱空(T*p){
foo(&nonst::value(*p));
}
(或者将模板进一步专门用于(非)常量指针。)这将有效地获取指向常量对象的指针,并移除常量,从而使(
foo
)能够变异对象。这将与实际公开的接口不一致,这意味着它在任何类型上都能平等地(并且预期地)工作
不仅如此,它还允许您使用实际常量对象的地址调用它,这将是未定义的行为
相反,如果绝对需要(并保证对象不是const),您应该在调用模板函数之前删除constness,以便它按预期工作(而不是改变const类型)
常数A*p;
删除(const_cast(p));//'foo()的错误`
这将有效地获取指向常量对象的指针,并删除常量,从而使其(foo
)能够变异对象。这将与实际公开的接口不一致,这意味着它在任何类型上都能平等地(并且预期地)工作
不仅如此,它还允许您使用实际常量对象的地址调用它,这将是未定义的行为
相反,如果绝对需要(并保证对象不是const),您应该在调用模板函数之前删除constness,以便它按预期工作(而不是改变const类型)
常数A*p;
删除(const_cast(p));//'foo()的错误`
如果您真的需要它,有一个/C++0x元函数:
const A *p;
Remove(const_cast<A*>(p)); // error for `foo()`
模板
脱空(T*p)
{
foo(const_cast(p));
}
测试:如果您真的需要它,有一个/C++0x元函数:
const A *p;
Remove(const_cast<A*>(p)); // error for `foo()`
模板
脱空(T*p)
{
foo(const_cast(p));
}
测试:您也可以首先对
常量无效*
执行静态强制转换
,然后对无效*
执行常量强制转换
:
template<typename T>
void Remove (T *p)
{
foo( const_cast< typename std::remove_const<T>::type *> (p) );
}
模板
脱空(T*p)
{
foo(const_cast)(static_cast(p));;
}
不可否认,它相当丑陋。您也可以先对
常量void*
执行静态强制转换
,然后对void*
执行常量强制转换
:
template<typename T>
void Remove (T *p)
{
foo( const_cast< typename std::remove_const<T>::type *> (p) );
}
模板
脱空(T*p)
{
foo(const_cast)(static_cast(p));;
}
无可否认,它相当丑陋。可能是@Kristopher的复制品,谢谢。我从那里得到了答案。还有,在
boost
中如何std::remove_cast
的想法已经实现了。@All,谢谢回复。最后,我使用了最简单的解决方案,foo((void*)p)代码>我一开始没想到。可能是@Kristopher的副本,谢谢。我从那里得到了答案。还有,在boost
中如何std::remove_cast
的想法已经实现了。@All,谢谢回复。最后,我使用了最简单的解决方案,foo((void*)p)代码>这一点我一开始并不在意。我同意,但这看起来很难看,必须在多个地方进行编辑。假设我只传递了可修改的const T*
(这不会导致任何UB)。@iammilind和你未来的维护者会感谢你的丑陋,因为它很容易追踪到,而不是“我在哪里意外地做了错误的事情,让constness在没有问我的情况下神奇地丢弃了”。如果它是“可修改的const T*”,为什么它被声明为常量?我同意Mark B的观点,这看起来像是在制造麻烦。我同意,但这看起来很难看,必须在多个地方进行编辑。假设我只传递了可修改的const T*
(这不会导致任何UB)。@iammilind和你未来的维护者会感谢你的丑陋,因为它很容易追踪到,而不是“我在哪里意外地做了错误的事情,让constness在没有问我的情况下神奇地丢弃了”。如果它是“可修改的const T*”,为什么它被声明为常量?我同意Mark B的观点,这看起来像是在为今后的麻烦设置。如何实现std::remove_const
发布在@KristopherHow给出的链接中std::remove_const
是如何实现的发布在@Kristopher给出的链接中