我一直在嘗試改編this 解決方案,以啓用普通(非成員)函數的存在。 在我的例子中,我有很多全局的字符串實用程序類型的函數,它們使用任何字符串類型T,例如T有一個char const* c_str() const
成員函數。調整檢查函數參數是否存在成員函數
目標是消除奇怪的編譯器錯誤消息,如果用戶試圖傳遞一些沒有c_str()
成員函數的類型T,而不是編譯器說的「c_str():no such member function」,I' d而是編譯器說:「foo(T &):沒有這樣的函數」其中foo
是全局函數。
這裏是適應代碼:
template<bool B,typename T = void>
struct enable_if {
typedef T type;
};
template<typename T>
struct enable_if<false,T> {
};
//
// This macro is adapted from the linked-to question -- this part works fine.
//
#define DECL_HAS_MEM_FN(FN_NAME) \
template<class ClassType,typename MemFnSig> \
struct has_##FN_NAME##_type { \
typedef char yes[1]; \
typedef char no[2]; \
template<typename T,T> struct type_check; \
template<class T> static yes& has(type_check<MemFnSig,&T::FN_NAME>*); \
template<class T> static no& has(...); \
enum { value = sizeof(has<ClassType>(0)) == sizeof(yes) }; \
}
// Declare an instance of the above type that checks for "c_str()".
DECL_HAS_MEM_FN(c_str);
// Define another macro just to make life easier.
#define has_c_str(STRINGTYPE) \
has_c_str_type<STRINGTYPE,char const* (STRINGTYPE::*)() const>::value
//
// A "ValidatedStringType" is a StringType that uses the above machinery to ensure that
// StringType has a c_str() member function
//
template<class StringType>
struct ValidatedStringType {
typedef typename enable_if<has_c_str(StringType),StringType>::type type;
};
// Here's the global function where I want to accept only validated StringTypes.
template<class StringType>
void f(typename ValidatedStringType<StringType>::type const& s) {
}
struct S { // Class for testing that has c_str().
char const* c_str() const {
return 0;
}
};
struct N { // Class for testing that does not have c_str().
};
using namespace std;
int main() {
S s;
N n;
cout << has_c_str(S) << endl; // correctly prints '1'
cout << has_c_str(N) << endl; // correctly prints '0'
f(s); // error: no matching function for call to 'f(S&)'
}
然而,如上圖所示,編譯器不「看」 f(S&)
- 爲什麼不呢?
僅供參考:f()採用S const而不僅僅是S沒有區別。同樣使's'const沒有任何區別。最後,消除'&'沒有任何區別。 – 2011-01-23 04:35:37