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

时间:2016-10-18 14:26:55

标签: c++ templates c++14 template-specialization type-deduction

我很难理解以下代码

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;
}

出现在答案https://stackoverflow.com/a/7943765/7006673中。

在这里,

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

似乎表明模板类的专业化

template <typename T>
struct function_traits

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

非常感谢提前。

2 个答案:

答案 0 :(得分:2)

这是部分专业化。它不能像“{1}}之类的”任何东西“,但它仍然有一些变化,所以它不是一个完整的专业化。

此外,您要查找的内容是原始struct / class的模板行中的类型数以及专业化中名称后面的typename T。这有点奇怪,因为它不对称。

在您的部分专业化中:

<...>

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

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

答案 1 :(得分:2)

  

这是什么样的专业化?

这是partial specializationtype_traits显式实例化为:

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

但此T取决于ReturnTypeClassTypeArgs。这就是为什么你在声明中没有template <>(那将是full specialization),而是一个模板声明,其中包含描述特定类型T的新参数。

  

如何推导模板参数ClassType,ReturnType和Args?

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

这是SFINAE的一个例子。