有关如何使用此代码段实现SFINAE的问题

时间:2019-07-20 05:42:11

标签: c++ logic implementation sfinae

参考

SFINAE

该问题与以下代码段有关:

template<typename T>
class is_class {
    typedef char yes[1];
    typedef char no [2];
    template<typename C> static yes& test(int C::*); // selected if C is a class type
    template<typename C> static no&  test(...);      // selected otherwise
  public:
    static bool const value = sizeof(test<T>(0)) == sizeof(yes);
};

在上述类模板定义中,public的{​​{1}}定义使用在类模板的实例化中使用的参数is_class<T>::value实例化嵌套的静态模板函数test T

如果以上解释正确,我有以下问题:

  1. 如何解释嵌套静态模板函数is_class的重载版本?

SFINAE如何使用以上重载为给定的test填充模板类value的公共布尔变量is_class<T>,并根据{{ 1}}?我不确定我了解如何在T的实例化中传递似乎是随机整数值sizeof(test<T>(0)) == sizeof(yes)的情况下,应该选择还是消除任何重载?有人可以举例说明吗?

  1. 使用0test<T>这两种嵌套类型(它们都已被类型定义为yes[1])的逻辑对我也不清楚。假设no [2]是大小为1的char数组的类型别名,而char是大小为2的char数组的类型别名,如何使用SFINAE将此逻辑集成到重载选择/消除中?

欣赏您的想法。

1 个答案:

答案 0 :(得分:1)

让我们清除一些误会:

  1. yes[1]不是类型。 yes是一种类型,它是char [1]的别名。
  2. no[2]不是类型。 no是一种类型,它是char [2]的别名。

对于重载解析,如果test(...)T,则class的优先级较低。因此,调用test<T>(0)将解析为第一个重载,其返回类型为yes&。因此,

sizeof(test<T>(0)) == sizeof(yes)的计算结果为
sizeof(yes) == sizeof(yes),其值为true

如果T不是类,则没有int T::*。那就是SFINAE的一部分。在这种情况下,选择test(...)作为重载,其返回类型为no&。因此,

sizeof(test<T>(0)) == sizeof(yes)的计算结果为
sizeof(no) == sizeof(yes),其值为false