使用LVALUE参考时Sfinae,但使用RVALUE REF时成功
我搜索了,但实际上找不到答案,为什么只有在Lvalue Ref通过论点时会发生Sfinae,但是当Rvalue Ref通过ARG时,构建成功:
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));
}
I searched but really couldn't find an answer why SFINAE happens only when the argument is passed by lvalue ref, but the build succeeds when the arg is passed by rvalue 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));
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
当您拥有
所谓的转发参考时。即使它看起来像是RVALUE参考,此参考类型也可以与LVALUES或RVALUE绑定。它的工作方式是,当您将lvalue传递给
f
,atype
被推荐为t&amp;
,而当您传递rvalueAtype 仅推荐为
t
。因此,当您进行
f(a);
atype
被推导为a&lt; int&gt;&amp;
,然后尝试形成返回类型a&lt; int&gt; :: member_type
无效,因为参考没有类型成员。相反,当您执行
F(std :: Move(a));
, atype 被推荐为a&lt; int&gt;
and code> anda&lt ; int&gt;
确实具有member_type
类型成员。要解决此问题,您可以使用
std :::::::: decay_t
喜欢When you have
You have what is called a forwarding reference. Even though it looks like an rvalue reference, this reference type can bind to lvalues or rvalues. The way it works is when you pass an lvalue to
f
,AType
gets deduced to beingT&
, and when you pass an rvalueAType
gets deduced to justT
.So, when you do
f(a);
AType
gets deduced asA<int>&
, and you try to form the return type ofA<int>&::member_type
which is invalid as references do not have type members.Conversely when you do
f(std::move(a));
,AType
gets deduced toA<int>
andA<int>
does have amember_type
type member.To fix this you can remove the reference-ness of type by using
std::decay_t
like