2016-09-28 99 views
5

考慮下面的代碼:decltype(auto),追蹤返回類型和sfinae:我們可以混合它們嗎?

auto f() -> decltype(auto) { /* do whatever you want here */ } 
int main() { f(); } 

返回類型推導並decltype(auto)用作後返回類型。
下面的代碼是一個稍微修改的(實際上,sfinae'd)版本:

struct S { static void f() {} }; 
struct T {}; 

template<typename U> 
auto f(int) -> decltype(U::f(), void()) { 
    // do whatever you want here 
} 

template<typename> 
auto f(char) -> decltype(auto) { 
    // do whatever you want here 
} 

int main() { 
    f<S>(0); 
    f<T>(0); 
} 

如果你在考試採取這樣的功能:

template<typename U> 
auto f(int) -> decltype(U::f(), void()) { 
    // do whatever you want here 
} 

的問題是:是否有可能使用尾隨返回類型來做sfinae並且仍然具有推導出的返回類型?
我的意思是像下面的代碼(不工作,當然):

template<typename U> 
auto f(int) -> decltype(U::f(), auto) { 
    // do whatever you want here 
} 

注:我不是在尋找涉及模板參數的替代方法,我知道他們和我」米只是好奇,知道如果是一個可行的解決方案。

+1

不要以爲這是可能的,但你想要的類型推斷爲'auto'或者'decltype(auto)'? – Holt

+0

不要以爲這裏有什麼可以做的。特意扣除退貨類型不要SFINAE。 – Xeo

+0

@Holt好問題,我會說在第一個例子中有'decltype(auto)',但是如果你知道如何將它推斷爲'auto',它也可以是一個很好的答案。 – skypjack

回答

4

decltype(auto)是一個不可分割的結構(就好像它是一個像decltype_auto這樣的關鍵字)。除此之外,auto不能用作decltype(x)中的獨立實體,因爲這會阻止x成爲有效的表達式。

0

不是答案,而是使用void_t的可能解決方法。

至少它幹成你想要做什麼:

template<typename... Ts> struct make_void { typedef void type;}; 
template<typename... Ts> using void_t = typename make_void<Ts...>::type; 


struct S { static int f() { return 3; } }; 
struct P { static int p() { return 4; } }; 
struct T {}; 

template<typename U, void_t<decltype(U::f())>* = nullptr > 
auto f(int) -> decltype(auto) 
{ 
    // do whatever you want here 
    std::cout << "f1\n"; 
    return U::f(); 
} 

template<typename U, void_t<decltype(U::p())>* = nullptr > 
auto f(int) -> decltype(auto) 
{ 
    // do whatever you want here 
    std::cout << "f3\n"; 
    return U::p(); 
} 

template<typename> 
auto f(char) -> decltype(auto) { 
    std::cout << "f2\n"; 
    // do whatever you want here 
} 

int main() { 
    std::cout << f<S>(0) << '\n'; 
    std::cout << f<P>(0) << '\n'; 
    f<T>(0); 
} 
0

可以void(*)()類型的其他參數,將其作爲默認參數,因此SFINAE添加的功能和分配尾隨返回類型的拉姆達可以通過拉姆達應用:

template<typename U> 
decltype(auto) f(int, void(*)() = []()->decltype(U::f(), void()) {}) 
{ 
    // do whatever you want here 
} 
相關問題