【发布时间】:2016-01-21 18:41:17
【问题描述】:
我正在考虑删除一些未使用的重载,并触发了编译错误,编译器称这是模板替换错误。但是我认为“替换失败不是错误”,无论如何,为什么删除过载会导致它?
简单的开始:
#include <string>
int ParseInt(const char *);
int ParseInt(std::string);
bool F(int(*)(const char *));
bool User() {
return F(ParseInt);
}
这里,User() 使用解析例程的地址调用 F。一切都很好。 ParseInt 已重载,但只有一个重载与 F 的签名匹配。
输入 F 的模板化重载:
bool F(int(*)(const char *));
template <typename T>
struct MetaDeduce {
typedef typename T::X type;
};
template <typename T>
typename MetaDeduce<T>::type F(const T&);
现在有一个奇怪的 F 模板重载,但没关系,因为函数指针无论如何都没有名为 X 的成员。一切都编译好了,一切都很好。
直到……
#include <string>
int ParseInt(const char *);
// int ParseInt(std::string); // commenting this out caused a compiler error!
bool F(int(*)(const char *));
template <typename T>
struct MetaDeduce {
typedef typename T::X type;
};
template <typename T>
typename MetaDeduce<T>::type F(const T&);
bool User() {
return F(ParseInt);
}
从 Godbolt (http://goo.gl/2Yd04p) 可以看出,这会产生一个奇怪的编译错误:
10 : error: type 'int (const char *)' cannot be used prior to '::'
because it has no members
typedef typename T::X type;
^
14 : note: in instantiation of template class 'MetaDeduce<int (const char *)>'
requested here
typename MetaDeduce<T>::type F(const T&);
^
WTF???看起来编译器正在抱怨替换失败,但为什么以前不是问题?无论如何,我认为替换失败不是错误!怎么回事?
【问题讨论】:
标签: c++ templates sfinae overloading template-argument-deduction