我正在寻找删除一些未使用的重载,并触发编译错误,编译器说这是一个模板替换错误。但我认为“替代失败并不是一个错误”,无论如何,为什么要消除超载导致它?删除未使用的重载会导致编译错误?
简单的开始:
#include <string>
int ParseInt(const char *);
int ParseInt(std::string);
bool F(int(*)(const char *));
bool User() {
return F(ParseInt);
}
在这里,用户()是调用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反正成员。一切顺利,一切都很好。
UNTIL ....
#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 ???它看起来像编译器抱怨替代失败,但为什么之前没有这个问题?无论如何,我认为替代失败并不是一个错误!这是怎么回事?
返回类型中'typename MetaDeduct :: type'是直接上下文中的 - 如果'MetaDeduct'没有名为'type'的成员类型,那么您将获得SFINAE。然而,'MetaDeduct'的定义不是直接的上下文,并且在那里发生错误,所以这是一个严重的错误。 –
@ T.C。谢谢,并更新。 – TemplateRex