2013-03-14 38 views
3

我想有通過引用接受臨時值和非臨時值的模板函數?

template <class T> 
void foo(T &t); 

是能夠接受的臨時爲好,不影響通過參考接受其他的目的和要求他們非const方法。可能在C + + 03?

我意識到我可能迫使用戶將其對象的所有方法聲明爲const,和所有成員mutable然後用const T &t參考,但是這是一個醜陋的解決方法。

+0

假設'foo'試圖修改這些臨時對象是否正確?爲什麼? – 2013-03-14 16:59:09

+1

不知何故,你的主題(與「價值」的部分)不符合你的問題描述的其餘部分... – PlasmaHH 2013-03-14 16:59:33

+1

在C++ 11這是通用的引用是...但這不是一個功能的存在在C++ 03中 – 2013-03-14 17:14:33

回答

1

您可以創建需要使用const類型的參考,使副本的非const第二功能類型參考。

template <class T> 
void foo (T &t); 

template <class T> 
void foo (const T &x) { 
    T copy(x); 
    foo(copy); 
} 

示範可以發現here

該技術的侷限性在於它無法區分臨時對象與真實對象const。這樣做的後果是,您的原始foo()本來不允許自己通過const對象。這個建議將允許他們,因此你失去了最初提供的一些安全。您可以通過重新命名foo的常量類型版本,使之與foo_for_temp類似,從而彌補這一點。然後,主叫方會知道該功能的意圖。

+0

如果非臨時性屬於「const」限定類型,該怎麼辦? – 2013-03-14 17:22:16

+1

@AndyProwl:上面的代碼無法區分const對象和臨時對象。但Irfy的函數原型無論如何都不適用於const限定類型。 – jxh 2013-03-14 17:24:48

+0

確實,這意味着它會編譯,而原始函數在用const限定類型的參數調用時(而且應該)不會編譯。 – 2013-03-14 17:31:52

0

其中一個,但危險的解決方案是將const T &作爲函數參數,然後const_cast <>它到T &。你將有你傳遞給函數什麼要小心,因爲它很容易導致未定義行爲:

template <class T> 
void foo(const T &ct) 
{ 
    T &t = const_cast<T>(ct); 
    // ... 
} 
4

在C++ 03中,無法推斷傳遞給函數的參數是左值還是右值。

我想這就是爲什麼你的問題的標題寫着「按值接受臨時工」的原因:如果這樣的機制存在,你可以創建一個函數(模板),其確定的參數類型是否應該T&或基於這些信息,

這正是支持的類型推演機械在C++ 11的作用:

template<typename T> 
void foo(T&& t); 
//  ^^^ 
//  lvalue of type A is passed: T = A&, signature = foo(A& t) 
//  rvalue of type A is passed: T = A, signature = foo(A&& t) 

但正如上面提到的,這是不可能在C++ 03,正是因爲它缺乏確定的方式表達式的值類別。

你提到的(強制所有對象有const成員函數)的可能性不是一種解決方法(甚至沒有一個醜陋的一個):如果成員函數都是const,這意味着foo()將不需要改變的狀態其輸入。這又意味着它可能需要一個const&,並解決問題。

您可能是想讓那些const成員函數執行const_cast<>以便更改對象的狀態,但是您可以再次在foo()中執行相同的操作。這是一個壞主意的原因是,在這兩種情況下,您都不能輸入foo()輸入類型爲const的對象,並且您可能不知道這是否是這種情況。

+0

+1的解釋,但我接受了一個較不常用的解決方案(沒有通過const限定的對象)適用於我的情況。 – Irfy 2013-03-25 12:19:43

+0

我不明白&&的意思,但是隨着你的解釋,它突然被點擊了。非常感謝。 – ioquatix 2017-11-02 21:41:20