[英]Inferring parameter of most template objects, but being explicit with others when calling a template function?
我注意到現代C ++(C ++ 11等)有時可以在傳遞給函數時推斷模板對象的int
模板參數,而不使用角度括號顯式傳遞int
值。
但是,如果我想要一個函數參數怎么辦:
bitset<N_OLD>
將int
模板參數自動推斷為函數輸入,並將函數返回值:
bitset<N_NEW>
使用角度括號或套管調用函數時要明確指定。 這可能嗎? 例:
#include <bitset>
using namespace std;
// expand or truncate bitset without sign extension
template<int N_NEW, int N_OLD>
bitset<N_NEW>
bresize(const bitset<N_OLD> value)
{
return bitset<N_NEW> {value.to_ullong() & ((1<<N_NEW)-1) };
}
例如,有可能:
bitset<16> x {0xABCD};
// version explicit everything (Not what I want)
auto y2 = bresize<32, 16>(x);
//Inference Attempt #1
auto y1 = bresize<32>(x);
//Inference Attempt #2
bitset<32> y3 = bresize(x);
//Inference Attempt #3
auto y4 = (bitset<32>)bresize(x);
我只是想了解在上述場景中推斷模板大小參數時的規則是什么。 目標是盡可能地推斷出bitset
的輸入大小,但要明確輸出大小。 這在C ++ 11中是否可行?
我會給出一個通用的答案,然后我會告訴你如何將它應用到你的案例中。
模板參數不能僅從返回類型中推斷出來。
template <class T, class R>
auto foo(T) -> R;
R
永遠無法推斷出來。 因此,在調用foo
時,您需要始終顯式。
因為R
在模板參數中位於T
之后,這意味着您在指定R
時也需要指定T
,即使T
是可抵扣的,例如foo<int, double>(24)
。
解決方案非常簡單:首先放置不可推導的模板參數:
template <class R, class T>
auto bar(T) -> R;
你可以這樣稱呼它:
bar<double>(24); // R explicit to double, T deduced as int from the parameters
template <class T, class U>
auto foo(T, U) -> U
這里可以推導出U
因為它可以從參數中推導出來。
如果不可抵扣模板參數依賴於另一個可抵扣模板參數,那么您可以從免賠額參數計算它:
template <class T>
auto foo(T) -> std::decay_t<T>
首先, std::bitset
的模板參數類型是std::size_t
而不是int
。 僅這一點就會導致演繹問題。 先解決這個問題。
接下來要確保首先使用不可抵扣的模板參數:
template<std::size_t N_NEW, std::size_t N_OLD>
std::bitset<N_NEW>
bresize(std::bitset<N_OLD> value) { /* ... */ }
然后你可以把bresize
稱為:
bresize<32>(x);
此外,如果N_NEW
可以從N_OLD
計算constexpr
,那么您可以完全跳過顯式參數:
template<std::size_t N_OLD>
std::bitset<N_OLD * 2>
bresize(std::bitset<N_OLD> value) { /* ... */ }
要么
template<std::size_t N_OLD, std::size_t N_NEW = N_OLD * 2>
std::bitset<N_NEW>
bresize(std::bitset<N_OLD> value) { /* ... */ }
要么
constexpr auto new_width(std::size_t old_width) => std::size_t
{
return old_width * 2;
/* or any constexpr allowed body */
};
template<std::size_t N_OLD>
std::bitset<new_width(N_OLD)>
bresize(std::bitset<N_OLD> value) { /* ... */ }
要么
template<std::size_t N_OLD, std::size_t N_NEW = new_width(N_OLD)>
std::bitset<N_NEW>
bresize(std::bitset<N_OLD> value) { /* ... */ }
一些小的偏離主題的挑剔: const T
作為參數沒有多大意義。 使用const T&
或T
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.