template<typename T>
struct Wrap {
Wrap(T *p) {}
};
#ifdef TEMPLATE
template<typename T>
void foo (Wrap<T> t) {} // version-1
#else
void foo (Wrap<int> p) {} // version-2
#endif
int main () {
foo(new int);
}
编译#else
部分时,编译正常,选择版本-2。如果我尝试编译#ifdef
部分,我希望应该选择版本1。但编译器会给出错误,
错误:没有匹配函数来调用`foo(int *)'
我是否触及template foo
的不可删除部分?如果是,那么任何人都可以澄清不可推导区域的确切规则是什么?
答案 0 :(得分:3)
无法通过传递给构造函数的参数来确定类模板的类型。要知道哪些构造函数可用,编译器必须已经选择了Wrap
来实例化。
在#else
块中,您已明确选择实例化Wrap<int>
,因此编译器知道使用隐式Wrap<int>(int*)
构造函数。
也许是非正式的:一种类型是不可推导的,如果推断它的前提条件是知道要推断的类型是什么。