1樓:霧雨口口子
#include
#include
using
namespace
std;
#define GEN_MEMBER_FUNC_CHECK_CLASS(func_return_type, func_name, ...) \
struct HasMemberFuncInspector_##func_return_type##_##func_name ; \
template \
struct HasMember_##func_return_type##_##func_name : public decltype(HasMemberFuncInspector_##func_return_type##_##func_name::Check(0)){};
//test case
structA};
structB};
structC};
struct
D{};
GEN_MEMBER_FUNC_CHECK_CLASS(string
,false,0
)int
main()
2樓:fairlyblank
原因應該是template申明的型別,本身不能是個模板,如果要用模板的模板,應該類似這樣的寫法:
例如要申明乙個本身是乙個帶有兩個模板型別的型別T:
template class T>
3樓:朱涵俊
如果是只考慮public成員,gcc可以用typeof
typeof (testClass::testMember) i;
4樓:暮無井見鈴
我個人認為更適合的手段還是檢測函式呼叫表示式的合法性,而非檢測成員函式的名稱。(原因後述)
比如 C++20 requires (個人想多提及一下 requires 子句可以帶引數,然而 requires 子句的引數為了和函式引數保持一致而有些不便):
template
class ...Args >inline constexpr bool callable_with_memfun_v =// 或使用概念 requires(T &&t,Args &&... args); 或者 C++11 利用 decltype 的 SFINAE : namespace detail );template , class ...> auto test_callable_with_memfun (...) ->std:: false_type;} // namespace detail template class ...Args >struct callable_with_memfun :decltype (detail ::test_callable_with_memfun ...>(0 )){}; // 或使用變數模板( C++14 起),編譯效果應該更好( by Casey Carter ) 偏特化上的 SFINAE 看起來目前還是非標準的( CWG 2054 ),但一般編譯器都支援,而且主流標準庫實現都用到這種寫法,標準委員會也有些人直接這麼寫而未說這是非標準的。我們或許可以認為它實際上沒有移植問題。 前面已經有人給出了偏特化 SFINAE 的寫法,這裡不重複了。(我不怎麼懂古代 C++ ,暫不考慮古代 C++ 的寫法) 至於為什麼不適合…… 我們知道成員函式和非成員函式類似,都能過載。 倘若類提供了 begin 的兩個版本,乙個有 const 限定而另乙個沒有( STL 容器就是這種情況),則直接用 &T::begin 取非靜態成員函式的位址存在歧義。此情況下需要把這個過載集的位址轉型( static_cast 或 C 風格轉型)成單一的成員函式指標型別(比如 T:: const_iterator (T::*)() const ),而引數列表變得無法推導了。 到這裡可以看出不對勁了。即使不論更複雜的函式模板,我們面對這個過載集,是無法窮舉每乙個潛在的引數列表的。(注意有引數列表就可以推導返回型別了,雖然寫起來仍然麻煩) 從而 C++ 中目前還是做不到檢測「是否有名為某個識別符號的成員函式」的。不過加入靜態反射的話就可以了。 而僅檢測名字而不在乎呼叫表示式的話,意義可能不是很大。雖然繼承時可能有用。 另外私有成員也會帶來問題。不過 C++20 更改了特化上的訪問檢查。此後該問題仍可規約成前面提及的「需要指定具體的函式型別」。 實現上非虛成員函式的簽名不一定要和標準描述的一致,只要過載決議選擇的過載能有標準所要求的效果就行( [member.functions]/2 )。這至少允許實現新增額外的有預設實參的引數,或者把標準描述中不是模板的成員函式改成模板(為了滿足標準的約束)。 C++20 起,取標準庫函式(除了一些 iostream 相關的直接用作操縱符的函式,譬如 std::endl )的位址的效果都變成未指定,並且可以且不通過編譯( [namespace.std]/6 )。 不難看出,標準的傾向是只保證函式呼叫表示式的合法性。(只)檢測成員函式的名稱可能不是乙個好選擇。 5樓:Ubp.a 這邊寫成這樣沒有問題,你可以考慮改寫一下 建議把函式簽名直接作為使用者需要填寫的內容,而不是【拆開成 Ret,Args...,然後在內部分成多個】 另外考慮少了,應該是 normal, const, &, &&, const&, const&&,甚至還有 volatile,總共至少也得有2*2*3=12種情況,所以拆開寫不好(另外還有靜態成員函式,假設題意要的是非靜態成員函式吧,如果考慮靜態,那麼函式簽名上要加上物件型別) 6樓:stay template class = std ::void_t <>>struct HasToStringFunction :false_type {};template T>struct HasToStringFunction void_t (declval ())>> :true_type {};又要拿出這個萬能 std::void_t 了 dodoleon 直接用c 11的 std is base of 就可以判斷是否是通過乙個基類繼承下來的。 Certain Y template size t m constexpr auto string equal const char value n const char o m for in... 當乙個類包含陣列成員時,索引器的使用將大大簡化對類中陣列成員的訪問。定義類似於屬性也具有get和set訪問器。具體定義如下 修飾符 資料型別 this 索引型別 index set 索引器可以讓我們像訪問陣列一樣訪問類中的陣列成員。簡單點來說是因為IList定義了T this int index 方... FledgeXu 如果拋棄作業系統執行編譯好的 C 程式,執行它的過程和執行乙個作業系統基本上沒什麼區別了。首先你要先寫彙編,從實模式轉化為保護模式,然後讀取硬碟特定扇面 扇區 磁軌上的32位 C 程式,載入記憶體後並執行。在編寫 C 程式的過程也有很多要注意的地方,首先你無法再使用標準庫了,因為標...C 裡,如何在乙個類廠裡,用靜態方式判斷乙個類是否繼承自某個類??
c 中,如何判斷乙個類是否可以通過索引器取值?
C 如何編譯出乙個不需要作業系統的程式?