[英]Why shouldn't you `std::move(*const_cast<T*>(ele))` the elements of a `std::initializer_list`?
[英]Why doesn't const_cast work on arguments to std::function?
我正在提供成員函數的const和非const變體,其中我重用const版本來實現非const版本, 如本答案中所描述的每個Scott Meyers書籍。
const版本采用類型的參數:
const std::function< void (const Foo &) > &
vs非const采用類型的參數:
const std::function< void ( Foo &) > &
在實現中,我必須使用reinterpret_cast
因為const_cast
不起作用。
例如,:
const std::function< void (Foo &) > & Processor;
reinterpret_cast< const std::function< void (const Foo &) > & >( Processor );
VS
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
是不安全的。 例如,考慮這個(誠然,有些人為的)代碼:
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
的指針中,該struct
包含一個int
現在指向一個包含double
的struct
,打破了一些語言規則,其名稱目前不在我身上。 :-)
因為一般來說const_cast
這種方式不安全,語言規范不允許像這樣使用const_cast
,這就是為什么在你的情況下,即使操作直觀,語言也不允許使用const_cast
代碼。
我相當肯定在這里使用reinterpret_cast
會導致未定義的行為,因為語言認為std::function<T1>
和std::function<T2>
是不同的,當T1
和T2
不相同時,不兼容的類型。 它可能恰巧在您的系統上運行純粹巧合,但我不相信您可以安全地認為這將起作用。
reinterpret_cast
這里是未定義的行為。 const_cast
不合適,因為模板參數的const
不是你可以拋棄的東西。
解決這個問題的簡單方法是,不要這樣做。 擺脫一些參考。 交換誰實現它。
void Collection::ProcessCollection(std::function< void (const Foo &) > Processor) const
{
Collection * mutableThis = const_cast< Collection * >( this );
mutableThis->ProcessCollection( Processor );
}
void Collection::ProcessCollection(std::function< void (Foo &) > Processor)
{
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 ] );
}
}
std::function
存儲與它調用兼容的東西。
如果你選擇Foo&
,你可以調用一個期望Foo const&
它的Foo const&
。 所以你可以在std::function<void(Foo const&)>
存儲一個std::function<void(Foo const&)>
std::function<void(Foo&)>
。
在std::function
包裝內容可能涉及分配。 因此,您可能希望找到一個高質量的function_view<Sig>
來替換您對std::function
。
在另一條評論中,您聲明此代碼處於關鍵循環中。 完全消除std::function
是一個很好的舉動,或者至少減少類型擦除點擊並以某種方式將批量數據傳遞給它。
const / unest的反轉仍然是合適的; 我們用const表示const而不是const的變量,因為一個是協變運算,另一個是逆變運算。 看到這里 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.