【发布时间】:2016-03-24 06:33:53
【问题描述】:
我对 SFINAE 有基本的了解,例如enable_if 是如何工作的。我最近遇到了this answer,我花了一个多小时试图了解它的实际工作原理,但无济于事。
此代码的目标是根据类中是否包含特定成员来重载函数。这是复制的代码,它使用 C++11:
template <typename T> struct Model
{
vector<T> vertices;
void transform( Matrix m )
{
for(auto &&vertex : vertices)
{
vertex.pos = m * vertex.pos;
modifyNormal(vertex, m, special_());
}
}
private:
struct general_ {};
struct special_ : general_ {};
template<typename> struct int_ { typedef int type; };
template<typename Lhs, typename Rhs,
typename int_<decltype(Lhs::normal)>::type = 0>
void modifyNormal(Lhs &&lhs, Rhs &&rhs, special_) {
lhs.normal = rhs * lhs.normal;
}
template<typename Lhs, typename Rhs>
void modifyNormal(Lhs &&lhs, Rhs &&rhs, general_) {
// do nothing
}
};
在我的一生中,我无法理解这种机制是如何工作的。具体来说,typename int_<decltype(Lhs::normal)>::type = 0 对我们有什么帮助,为什么我们在这个方法中需要一个额外的类型(special_/general_)。
【问题讨论】:
-
在我看来,该示例无效;如果
Lhs是左值,则转发引用不会触发decltype(Lhs::normal)。应该是decltype(std::declval<Lhs>().normal) -
@PiotrSkotnicki 示例运行,我测试了它。
-
它编译,但你检查它是否给出正确的结果?
-
@Phantom 因为转发引用成为左值的左值引用,因此,例如
A&::normal永远无效(请参阅与号)