我有点问题。下一个代码是什么意思?
template<typename>
struct function_traits; // (1)
template<typename ClassType,
typename ReturnType,
typename... Arguments>
struct function_traits<ReturnType(ClassType::*)(Arguments...) const> { // (2)
...
};
template<typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
// (3) Why here inheritance?谢谢!
发布于 2016-09-07 17:34:19
你觉得这是个谜,这是可以理解的。我们大多数人在一开始就是这样做的。
首先:
template<typename>
struct function_traits; // (1)它声明了具有一个模板参数的模板类的一般形式,该模板参数是一个类型(class X、struct Y、int、float、std::string等等)。请注意,目前该模板已声明,但不能从该模板实例化任何类,因为该模板没有特殊化。甚至不是默认的。
第二:
template<typename ClassType,
typename ReturnType,
typename... Arguments>
struct function_traits<ReturnType(ClassType::*)(Arguments...) const> { // (2)
...
using result_type = ReturnType; // capture the template type into a typedef in the class namespace
};这定义了模板function_traits<typename T>的部分专门化,其中T是任何类的任何成员函数指针,它返回任何返回类型并接受任意数量的参数。因为已经为ReturnType分配了一个模板参数,这意味着允许该类的定义将其作为一个类型引用,从而推导出成员函数的result_type。
然而,在这个阶段,专门化并不有用,因为调用者需要在调用点指定完整的函数指针,就像这样:function_traits<&SomeClass::someFunction>和处理重载将是棘手的。
现在,第三部分进行了“接口”专门化,即对于任何类T,function_traits<T>都应该从function_traits<&T::operator()>派生。
template<typename T>
struct function_traits : public function_traits<decltype(&T::operator())> {};
// (3) Why here inheritance?因为在模板扩展中有这样一个特定的匹配项,所以它将只针对具有调用运算符(operator())的类型进行扩展。基类提供来自第二个专门化的返回类型,因此该模板能够捕获具有调用操作符的任何类型的返回类型。因为该类是从捕获返回类型的实际类派生的,所以result_type也是该类作用域的一部分。
现在我们可以这样写:
struct Foo {
int operator()();
};
using foo_ret = function_traits<Foo>::result_type;而foo_ret将是int。
还不明白吗?欢迎参加您的前6个月的模板编程。
https://stackoverflow.com/questions/39364484
复制相似问题