return true;
}
public:
const static bool value = hasToString<T>(nullptr);
};
好家伙,这也太复杂了!!完全没看懂。你是否有这样的感觉呢?如果你是第一次接触,感
觉比较复杂很正常,现在我们无需完全理解他,下面我们一步步慢慢说。
首先有两个 c++的其他知识先解释一下:constexpr 关键字和成员函数指针,了解的读者可以
直接跳过。
constexpr:表示一个变量或者函数为编译期常量,在编译的时候可以确定其值或者函数的返
回值。在上面的代码中,const static bool value 需要在编译器确定其值,否则不能在类中直
接复制。因此我们给 hasToString 函数增加了 constexpr 关键字。
成员函数指针:我们可以获取一个对象的成员函数指针,而在合适的时候,调用此函数。如
下代码
std::string (Cat::*p)() const = &Cat::toString; // 获取 Cat 的函数成员指针
Cat c;
std::string value = (c.*p)(); // 通过成员函数指针调用 c 的成员函数
可以看到成员函数指针的声明语法和函数指针很相似,只是在前面多了 Cat::表示是哪个类
的指针。
这里仅简单介绍,其他更详细的内容,感兴趣可以百度一下了解。
好,我们第一步先看到 HasToString 的 value 变量,他是一个 const static bool 类型,表示 T
类型是否有 toString 函数的结果。他的值来源于 hasToString<T>(nullptr),我们继续看到这个
函数。
hasToString 是一个返回值为 bool 类型的模板函数,由于其为 constexpr static 类型,使得其
返回值可以直接赋值给 value。他有两个重载实例:
第一个重载函数的参数为函数参数包
第二个重载函数的参数为 Helper 对象的的指针
我们暂时先不管 Helper 的内容,当我们调用 hasToString<T>(nullptr)时,他会选择哪个重载
函数?答案是不管 T 类型如何,都会先进入第二个重载函数。原因是,第二个重载函数相比
第一个更加特例化:实参与形参均为指针类型,根据模板函数匹配规则,他的优先级更高,
因此会选择第二个重载函数进行匹配。
到这里,我们已经可以明确,在编译时,不管 T 的类型如何,均会调用到 hasToString 的第
二个重载函数。这个时候,我们看到模板类 Helper,他的模板类型很简单,第一个模板参数
是 Y,而第二个模板参数则为第一个模板类型的对象值。