我提供了一个成员函数的 const 和非常量变体,我在其中重用 const 版本来实现非常量版本作为 described in this answer根据 Scott Meyers 的书籍。
const 版本接受一个类型的参数:
const std::function< void (const Foo &) > &
vs 非常量接受类型的参数:
const std::function< void ( Foo &) > &
在实现中,我必须使用 reinterpret_cast
因为 const_cast
不起作用。
例如:
const std::function< void (Foo &) > & Processor;
reinterpret_cast< const std::function< void (const Foo &) > & >( Processor );
对比
const std::function< void (Foo &) > & Processor;
const_cast< const std::function< void (const Foo &) > & >( Processor );
这不符合 const_cast
的意义吗?这只是语言定义中的疏忽,可能会在 C++2x 中得到修复,还是 const_cast
永远不会符合这里的精神?
这里是更完整的代码:
void Collection::ProcessCollection(const std::function< void (const Foo &) > & Processor) const
{
for( int idx = -1 ; ++idx < m_LocalLimit ; )
{
if ( m_Data[ idx ] )
{
Processor( m_Data[idx] );
}
}
const int overflowSize = OverflowSize();
for( int idx = -1 ; ++idx < overflowSize ; )
{
Processor( (*m_Overflow)[ idx ] );
}
}
void Collection::ProcessCollection(const std::function< void (Foo &) > & Processor)
{
const Collection * constThis = const_cast< const Collection * >( this );
const std::function< void (const Foo &) > & constProcessor
= reinterpret_cast< const std::function< void (const Foo &) > & >( Processor );
constThis->ProcessCollection( constProcessor );
}
最佳答案
一般来说,使用const_cast
是不安全的扔掉const
出现在模板参数中的 ness。例如,考虑这个(诚然,有点做作的)代码:
template <typename T> struct Wrapper {
int x;
};
template <> struct Wrapper<char *> {
double y;
};
在这里,一个指向 Wrapper<const char *>
的指针指向与 Wrapper<char *>
截然不同的对象, 所以做 const_cast
转Wrapper<const char *> *
进入Wrapper<char *> *
将导致指向 struct
的指针包含 int
现在指向 struct
包含 double
, 打破了一些我现在想不起名字的语言规则。 :-)
因为一般来说 const_cast
是不安全的这样,语言规范就不允许 const_cast
像这样使用,这就是为什么在您的情况下,即使操作具有直观意义,该语言也不允许使用 const_cast
的代码.
我相当确定使用 reinterpret_cast
这里会导致未定义的行为,因为语言考虑了 std::function<T1>
和 std::function<T2>
当 T1
时是不同的、不兼容的类型和 T2
不一样。它可能碰巧在您的系统上工作纯属巧合,但我不相信您可以安全地假设它会工作。
关于c++ - 为什么 const_cast 不能作用于 std::function 的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56589639/