[英]How does template argument deduction distinguish between an lvalue and a literal/compile-time value
這是與OP的constexpr對重載有用的解決方案有關的問題。
基本上,他用
template<class T>
typename std::enable_if<std::is_arithmetic<T>::value, int>::type
f(T&& n) { ... }
和
template<class T>
typename std::enable_if<!std::is_arithmetic<T>::value, int>::type
f(T&& n) { ... }
知道是否已使用f()
調用了編譯時變量(例如,文字: f(42)
)還是左值(例如,局部變量: f(argc)
)作為其參數。
問:如何運作? (我希望在兩個調用中都將調用第一個重載(即std::is_arithmetic<T>::value == true
))
這是一個完整的示例:
#include <iostream>
#include <type_traits>
using std::cout;
using std::endl;
template<class T>
constexpr
typename std::enable_if<std::is_arithmetic<T>::value,
int>::type
inline f(T&& n)
{
//cout << "compile time" << endl;
return 1;
}
template<class T>
typename std::enable_if<!std::is_arithmetic<T>::value,
int>::type
inline f(T&& n)
{
//cout << "run time" << endl;
return 0;
}
int main(int argc, char* argv[])
{
const int rt = f(argc);
constexpr int ct = f(42);
cout << "rt: " << rt << endl;
cout << "ct: " << ct << endl;
}
表單的模板功能
template <typename T>
void func(T&& t);
看起來好像需要一個r值參考。 但是實際上, T&&
這就是Scott Meyers所謂的通用引用 ,也稱為轉發引用。 根據參數的值類別,可能發生不同的事情。 讓我們看一下每種情況:
t是非常量左值,例如
int i = 0; func(i);
在這種情況下,T被推導為int
的左值引用,即T=int&
。
t是一個常量左值,例如
const int i = 1; func(i);
類似地,在這種情況下, T
被推導為const int&
。
t是一個右值,例如
func(1);
在這種情況下,正如我們可能預期的那樣,推導T
為int
這些推論之所以如此發生,恰恰與參考折疊的規則有關。 如果您有興趣,我強烈建議閱讀Scott Meyers關於該主題的文章。
上面的最后一種情況還說明了一點,在C和C ++中,文字(字符串文字除外)始終是右值。
這與enable_if
什么關系? 好吧,如果您的f
用整數字面量調用,則T
被推導為純int
。 顯然, is_arithmetic<int>
為true,因此第二個函數被SFINAE退出,第一個函數被調用。
但是,當用左值調用時, T
推導為(const) int&
。 引用不是算術運算,因此第一個函數消失了,僅剩下第二個函數要調用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.