具有非空模板参数列表的模板特化

Template specialization with non-empty template parameter list

我看不懂下面的代码

template <typename T>
struct function_traits
    : public function_traits<decltype(&T::operator())>
{};
// For generic types, directly use the result of the signature of its 'operator()'

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>
// we specialize for pointers to member function
{
  // ...
}

int main()
{
    auto lambda = [](int i) { return long(i*10); };

    typedef function_traits<decltype(lambda)> traits;

    // ...

    return 0;
}

出现在答案 中。

这里,

template <typename ClassType, typename ReturnType, typename... Args>
struct function_traits<ReturnType(ClassType::*)(Args...) const>

似乎表明模板的专业化class

template <typename T>
struct function_traits

但是,特化 template <typename ClassType, typename ReturnType, typename... Args> 的模板参数列表不为空(即不等于 template <>)。 有人可以帮我理解,这是什么专业化以及模板参数 ClassTypeReturnTypeArgs 是如何推导出来的?

非常感谢。

这是部分专业化。它不可能是一个 "anything" 就像只需要 typename T 的东西,但它仍然有一些可变性,所以它不是一个完整的专业化。

此外,您要匹配的是原始 struct/class 模板行中的类型数量和专业化名称后的 <...>。这有点奇怪,因为它是不对称的。

在你的部分专业中:

struct function_traits<ReturnType(ClassType::*)(Args...) const>

所有三种模板化类型组合起来仍然只创建一个类型 - 指向成员函数的指针。这与 "parent" 模板化类型的类型数量相同,即使该单一类型在专业化中被分解为 3 个额外的模板化类型。

// this is what I'm calling the "master template", this isn't an official term
template<class A, class B, ......., class N>
class Foo{};

template</*...This can have as many (or 0) entries as you need for this specialization...*/>
class Foo</*...This must have the same number as master template above, but can be broken down into as many smaller pieces as you want...*/> {};

What kind of specialization this is?

这是一个partial specializationtype_traits 显式实例化为:

T = ReturnType(ClassType::*)(Args...) const

但是这个T依赖于ReturnTypeClassTypeArgs。这就是为什么您在声明中没有 template <>(那将是 full specialization),而是带有描述特定类型 T.[=24= 的新参数的模板声明]

How the template parameters ClassType, ReturnType, and Args are deduced?

它们是在使用适合此专业化的表达式实例化模板时推导出来的。这里,ReturnType(ClassType::*)(Args...) const只能用指向方法的指针代替。

这是 SFINAE 的示例。