2016-12-15 62 views
1

所以我有一個類:模板參數包不能推斷`常量&`參數

struct C { 
    int x[10]; 

    int const& get(int i) const { return x[i]; } 

    template<typename... Ts> 
    auto& get(Ts... args) { 
    int const& (C::*f)(Ts...) const = &C::get; 
    return const_cast<int&>((this->*f)(args...)); 
    } 
}; 

和模板將根據需要生成非const吸氣,所以這成爲法律:

int& test(C& c) { 
    int i = 4; 
    int& r = c.get(i); 
    return r; 
} 

但如果我改變了原來的getter的參數類型的引用:

int const& get(int const& i) const { return x[i]; } 

const獲得者模板不能與const獲得者匹配。

很明顯,通過價值傳遞int並沒有什麼大不了的,把參數列表明確地傳遞給模板並沒有什麼大不了的,但是我有更復雜的參數和大量的重載,並且我想推斷我所有的非參數, const getters具有最低限度的複製粘貼。

有什麼辦法可以過去嗎?


我想過了,我可以在類內聲明的問題,參數列表,但留下的定義模板,這樣的說法匹配將有一定的指導意義。我試過(之前或之後的模板)添加以下的類:

int& get(int const& i); 

不幸的是這完全繞過了模板和鏈接錯誤的結果。向聲明中添加inlinetemplate似乎也無法解決問題。

+0

通過「無數重載」事實證明,我其實有兩個,但它是我關心的_principle_。我可能會晚一些。 – sh1

+0

我認爲你的編譯器應該抱怨'int&i = c.get(i)',因爲'int&'不是const。 –

+0

@Anders K.,這就是模板存在的原因。它通過調用const getter並從結果中剝離const來創建一個非const的getter。這對於從各種const和非const方法中使用相同的getter很有用。如果存在很多重載,那麼它會選擇具有與該調用相匹配的參數列表的那個。不幸的是,如果const getter採用引用參數,則「匹配」失敗,因爲該調用看起來像是按值調用。 – sh1

回答

2

爲什麼通過輔助指針指向成員函數來強制執行const成員函數的調用?在這種情況下,我使用const資格this

template<typename... Ts> 
auto& get(Ts... args) { 
    const C* const const_this = this; 
    return const_cast<int&>(const_this->get(args...)); 
} 
+0

哦,哎呀!因爲它是從另一個模板演化而來的,我嘗試在返回類型上獲得隱式匹配。 – sh1

+0

這確實使代碼工作(所以它回答了我的問題);但我爲什麼不清楚。一個替代版本,它接受一個函數指針參數,以便大部分的措辭可以應用於各種getter,仍然受到影響。 – sh1

相關問題