我搜索但真的找不到答案,為什么 SFINAE 僅在引數由左值 ref 傳遞時發生,但當 arg 由右值 ref 傳遞時構建成功:
template <typename T>
class A {
public:
using member_type = T;
};
template <typename AType>
typename AType::member_type f(AType&& m) {
typename AType::member_type res{};
return res;
}
void demo() {
A<int> a;
// ERROR: candidate template ignored: substitution failure
// [with AType = A<int> &]: type 'A<int> &'
// cannot be used prior to '::' because it has no members
f(a);
// BUILD SUCCESS
f(std::move(a));
}
uj5u.com熱心網友回復:
當你有
template <typename AType>
typename AType::member_type f(AType&& m)
您有所謂的轉發參考。盡管它看起來像一個右值參考,但這個參考型別可以系結到左值或右值。它的作業方式是,當您將左值傳遞給 時f,AType推斷為存在T&,而當您傳遞右值AType時,推斷為 just T。
因此,當您確實f(a); AType被推斷為A<int>&,并且您嘗試形成A<int>&::member_type無效的回傳型別時,因為參考沒有型別成員。
相反,當你這樣做時f(std::move(a));,AType會被推斷為A<int>并且A<int>確實有一個member_type型別成員。
std::decay_t要解決此問題,您可以使用like洗掉型別的參考性
template <typename AType>
auto f(AType&& m) {
typename std::decay_t<AType>::member_type res{};
return res;
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/490202.html
