2010-09-03 9 views
4

在C++中,編譯如下代碼:是否有可能在沒有黑客的情況下「constify」一個「std :: pair」字段?

std::pair <int, int> x; 
static_cast <std::pair <const int, int>*> (&x); 

給出了一個錯誤:

error: invalid static_cast from type ‘std::pair<int, int>*’ to type ‘std::pair<const int, int>*’ 

我或多或少明白爲什麼會發生,因爲CV-資格在模板參數列表類型可以原則上給出「不兼容」的結果。即使在這種情況下,編譯器也無法知道它。

無論如何,是否有一個非hackish方式來執行此轉換?我對使用reinterpret_cast的任何事情都保持警惕,因爲我之前一直使用type-punning方法解決問題。另外,我不能使用臨時對象,因爲這是在性能關鍵的代碼中。

編輯:

下面是我在做什麼。我正在實現一個自定義容器界面 - 兼容std::unordered_map。因此,其value_type需要是pair <const key_type, mapped_type>。對於一些優化,我需要內部存儲值爲pair <key_type, mapped_type>,沒有const。但是,如果我這樣做,我不能(沒有reinterpret_cast)在容器上實現迭代器,因爲它們需要返回對值的引用,並且我只引用了這些非常量對。

+0

你對此有何用處?我很難看到這將如何使用。 – 2010-09-03 18:30:34

+0

你可以保留兩個這樣的結構體,並定義一個從less const到更const的轉換函數。 – dirkgently 2010-09-03 18:33:33

+0

@詹姆斯麥克奈利斯:我的猜測是他有一個函數返回一對,另一個函數需要一對 * – 2010-09-03 18:38:33

回答

1

這不是一個演員,但你可以做到以下幾點:

std::pair<int, int> x; 
std::pair<const int, int> y(x); 

這要根據§ 20.2.2/4的工作。

+0

訣竅是'y.second'需要引用與'x相同的變量。秒'。也許'std :: pair y(x.first,x.second)'可能會起作用。 – 2012-01-05 20:24:00

0

如何:

template< typename T1, typename T2 > 
struct ref_pair { 
public: 
    typedef const T1 first_type; 
    typedef T2 second_type; 

    ref_pair(first_type& f, second_type& s) : f_(f), s_(s) {} 

    first_type& first() {return *f_;} 
    second_type& second() {return *s_;} 
private: 
    first_type* f_; 
    second_type* s_; 
}; 

我知道,這是不同的,這些都是功能。如果你真的很絕望,你可以將firstsecond轉化爲一些代理類型的對象,這些代理類型會延遲評估*f_*s_
但是,最終總有一種方法可以讓用戶分辨出不同之處。


我認爲以下是合理的安全和便攜,雖然,當然,與reinterpret_cast沒有保證:

std:::pair<const int,int>& rx = reinterpret_cast<std:::pair<const int,int>&>(x); 

感覺髒,但。我現在要去洗手。

+0

http://stackoverflow.com/questions/14272141/is-casting-stdpairt1-t2-const-to-stdpairt1-const-t2-const-safe – 2013-01-11 15:42:07

相關問題