簡體   English   中英

推斷大多數模板對象的參數,但在調用模板函數時與其他模板對象一起顯式?

[英]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中是否可行?

我會給出一個通用的答案,然后我會告訴你如何將它應用到你的案例中。

模板參數不能僅從返回類型中推斷出來。

例1

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

例2

template <class T, class U>
auto foo(T, U) -> U

這里可以推導出U因為它可以從參數中推導出來。

例3

如果不可抵扣模板參數依賴於另一個可抵扣模板參數,那么您可以從免賠額參數計算它:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM