2017-06-23 26 views
9

在C++中17,我們有std::void_t,這使得SFINAE看起來要好很多:是否有其他類型的void_t的標準泛化?

template <typename T> 
std::void_t<decltype(T::prop)> foo() { /* stuff */ } 

模板功能將只存在,如果存在T::prop

如果T::prop存在,模板功能foo()將是相同的:

template <typename T> 
void foo() { /* stuff */ } 

否則,代碼就等於沒有宣佈foo()可言。

是否有其他類型的標準庫的std::void_t任何概括,如下列:

template<typename T, typename...> 
using generic_t = T; 

,使下面的代碼將是有效的?

template <typename T> 
std::generic_t<int, decltype(T::prop)> foo() { /* stuff */ } 

這將等同於

template <typename T> 
int foo() { /* stuff */ } 

如果T::prop存在?

+3

爲什麼不'decltype (T :: prop,int())'?這不行嗎? – Justin

+2

@Justin因爲'std :: void_t'忽略了它的參數類型。無論如何,它都將是「無效的」。 – Rakete1111

+1

我想你可以做'std :: tuple_element_t <0,std :: tuple >' –

回答

4

你爲什麼需要這樣的概括? void_t有點特別,它可以幫助您輕鬆編寫類型特徵,因爲您可以使用某種類型的主類型,默認爲void,使用void_t的特化類型。例如:

template <class T, class = void> 
struct has_prop : std::false_type { }; 

template <class T> 
struct has_prop<T, std::void_t<decltype(T::prop)>> : std::true_type { }; 

這並不是說有什麼特別之處void,你只需要在某些類型的初級和專業化之間的約定。

void_t沒有什麼意義,如果你只是直接在SFINAE中使用它。你可以只堅持表達別處:

template <typename T, class = decltype(T::prop)> 
void foo() { /* stuff */ } 

此時返回類型是你無論如何檢查的條件完全分開的,所以如果你想int

template <typename T, class = decltype(T::prop)> 
int foo() { /* stuff */ } 
+0

如果我直接在SFINAE中直接使用它,爲什麼'void_t'沒有多大意義? – Bernard

+1

@Bernard'void_t'用於將類型強制轉換爲'void',但通常情況下不需要sfinae中的行爲。我最後的兩個例子做你想做的事,同時也有一個明確的返回類型。 – Barry

1

它可能不存在。它沒有鏈接到文檔中,因此我懷疑它的存在。但是你可以自己建這樣的類型:

template <class type, class... sfinae_expressions> 
using generic_t = type; 
+3

OP有'generic_t'更好的實現。你的這些參數並不是可變的,在某些情況下可能有用。 – Rakete1111

+0

@ Rakete1111我添加了variardic模板。現在它需要任意數量的類型 – OutOfBound

+0

這個簡單的表單[可能不起作用](http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#1558)。 –

相關問題