非模板化struct / class的模板化成员函数 - 什么是默认类型?

时间:2013-02-14 19:12:19

标签: c++

我见过这样的代码:

#include <iostream>

// member_function_templates.cpp
struct X
{
   template <class T> void mf(T* t) {
     std::cout << "in mf t is: " << *t << std::endl;
   }
};

int main()
{
   int i = 5;
   X* x = new X();
   x->mf(&i); //why can this be called without specifying a type as in: x->mf<int>(&i) ??
}

我的问题在于主要的评论。你为什么打电话:

x->mf(&i);

...没有指定类型?直觉说它应该被称为:

x->mf<int>(&i);

...但显然不必像这样调用(上面用我的方式编译gcc 4.7 - 没有明确指定模板。)

而且,如果你在没有指定模板类型的情况下调用它,那么T的类型是什么(在模板函数定义中)? (我猜它默认为你将函数mf作为参数传递给它的类型,但进一步解释它的工作方式会很好)

1 个答案:

答案 0 :(得分:3)

这是模板类型推导,它适用于所有模板函数,而不仅仅是非模板类的成员。基本上,编译器能够根据函数的参数推断(遵循标准中的一组规则)类型T的含义。当编译器看到对mf(&i);的调用时,它知道iint,因此参数是int*,这意味着您希望重载具有T==int {1}} (*)

如果要强制模板的特定专业化,仍可以提供一组特定的模板参数。例如,如果您希望模板的参数不是推导出的参数,而是可以从中转换的参数:

template<typename T>
void foo(T arg) {...}

int i = 10;
foo(i);             // calls foo<int>(i)
foo<double>(i);     // calls foo<double>(static_cast<double>(i))

(*)它稍微复杂一点,因为可能有多个T类型的参数有效,但语言中的规则决定了什么特定的{em}推导出<{1}} 。在这种情况下,它是T