我正在實作一個包裝一些基類物件的包裝類。我希望包裝器盡可能不引人注意,因此,我已經多載了->運算子以回傳對包裝物件的參考,以便提供對基類介面的即時訪問。
此外,我希望我的包裝器型別也實作基類實作的所有運算子,并將相應的運算子呼叫委托給包裝的物件。但是,由于我希望能夠包裝任何任意基類,所以我不知道先驗地為包裝類定義了哪些運算子。
我目前的方法包括為我的包裝器定義所有運算子并使用 SFINAE 禁用那些未包含在基類實作中的實作。
運算子多載的實作基本上總是這樣
auto operator <operator> (const Wrapper &lhs, const Wrapper &rhs) { return lhs.get() <operator> rhs.get(); }
auto operator <operator> (const Wrapper &lhs, const Base &rhs) { return lhs.get() <operator> rhs; }
auto operator <operator> (const Base &lhs, const Wrapper &rhs) { return lhs <operator> rhs.get(); }
<operator>相應的運算子在哪里。因為,我不想為所有運算子復制此代碼,所以我定義了一些宏來為我創建定義。
這適用于大多數運算子,但現在我也想支持各種賦值運算子(例如*=)。在這里,lhs引數不能const是通過操作員的操作修改的。
我可以單獨生成這些,但我認為必須有一種方法可以lhs根據 constexpr 布林值(可作為宏引數)簡單地將引數設為 const 或 non-const。因此,我創建了一個模板化的幫助器cond_add_const< T, bool >,它回傳const Tif passedtrue和Tif passed false。
現在的問題是,涉及Base類作為直接引數的多載由于模板引數推導失敗而無法解決。問題似乎是,為了應用我的條件常量,我基本上將相應的型別替換為,cond_add_const< T, true >::type并且顯然左側的所有內容::都不參與模板引數推導。
這看起來相當令人沮喪,而且對于我的簡單案例來說,感覺應該有可能繞過這個限制(或選擇一種不需要它的方法),但我就是想不出一個(不涉及復制代碼)。有任何想法嗎?
MWE說明了我的問題:
#include <type_traits>
template< typename T, bool is_const > struct cond_add_const {
using type = typename std::conditional< is_const, typename std::add_const< T >::type, typename std::remove_const< T >::type >::type;
};
template< typename T > void myFunc(typename cond_add_const< T, true >::type lhs, int rhs) {
}
int main() {
myFunc(1, 2);
}
編譯此代碼段,g 結果為
test.cpp: In function ‘int main()’:
test.cpp:11:13: error: no matching function for call to ‘myFunc(int, int)’
11 | myFunc(1, 2);
| ^
test.cpp:7:29: note: candidate: ‘template<class T> void myFunc(typename cond_add_const<T, true>::type, int)’
7 | template< typename T > void myFunc(typename cond_add_const< T, true >::type lhs, int rhs) {
| ^~~~~~
test.cpp:7:29: note: template argument deduction/substitution failed:
test.cpp:11:13: note: couldn’t deduce template parameter ‘T’
11 | myFunc(1, 2);
|
uj5u.com熱心網友回復:
您可以將模板函式轉換為類的非模板friend函式:
template <typename T>
struct Wrapper
{
// ...
friend void myFunc(typename cond_add_const<Wrapper<T>, true >::type lhs, T rhs)
{ /*...*/ }
};
演示
有一些警告:
- 該
friend函式只能通過“ADL”找到(因此至少一個引數應該是該Wrapper型別)。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/519907.html
標籤:C 模板模板参数推导
