我正在尋找刪除一些未使用的重載,並觸發編譯錯誤,編譯器說這是一個模板替換錯誤。但我認爲「替代失敗並不是一個錯誤」,無論如何,爲什麼要消除超載導致它?刪除未使用的重載會導致編譯錯誤?
簡單的開始:
#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