2

我很想在這裏,但我想要對這個問題進行精確的描述。我想單獨通過他們的名字改進檢測成員模板的實現,但是我遇到了一個障礙。我無法找到任何方法來檢測超載的static /非static成員函數。這個問題非常重要的部分是,我不能使用this trick,因爲它檢測到任何名稱(我已經在當前實現中使用它,有點用處),並且我不能指定類型,因爲它忽略了點單獨使用名字。有沒有辦法通過名字來檢測重載的成員函數? (不檢測名字)

僅供參考,請參閱我的other question。我在那裏發佈當前has_member_template_bar實施方案an answer。我認爲我不應該在這個問題上發表全部內容。

問題保持不變 - 我們能否檢測到重載的成員函數,但沒有指定它們的參數,或者使用提到的技巧?我知道我可能會要求不可能的事情,但是它永遠不會受到傷害。

+0

有趣的問題,這很有趣,以找到一個方法來做到這一點。 +1 – skypjack

回答

1

問題保持不變 - 我們能否檢測到重載的成員函數,但沒有指定它們的參數或使用提到的技巧?我知道我可能是要求不可能的,但它永遠不會受到傷害要求

實際上,這不是不可能的。
它遵循最小,工作示例:

template<typename T, typename R, typename... A> 
void proto(R(T::*)(A...)); 

template<typename, typename = void> 
constexpr bool has_single_f = false; 

template<typename T> 
constexpr bool has_single_f<T, decltype(proto(&T::f))> = true; 

struct S { 
    void f(int) {} 
    void f(char) {} 
}; 

struct U { 
    void f() {} 
}; 

int main() { 
    static_assert(not has_single_f<S>, "!"); 
    static_assert(has_single_f<U>, "!"); 
} 

當然,你需要添加更多的東西成員方法和數據成員來區分,但它是微不足道的添加它們(見頭type_traits),我試過儘可能減少示例。

其基本思想是如果給定函數過載,則調用proto失敗,因爲它是模糊呼叫
無論如何,由於SFINAE規則,該錯誤被丟棄。
參數不需要根據請求指定。
另請注意,proto不需要定義,但重要的是其返回類型爲void。否則,您必須調用稍微修改,以decltype因爲它遵循:

template<typename T> 
constexpr bool has_single_f<T, decltype(proto(&T::f), void())> = true; 

正如你從示例代碼中看到,static_assert■確認fS超載,這是不是在U


上述示例基於模板變量,它們是自C++ 14以來的語言的一部分。
如果你喜歡衆所周知基礎結構解決方案,它與C++ 11的作品,你可以使用下面的檢測:

#include<type_traits> 

//... 

template<typename, typename = void> 
struct has_single_f: std::false_type {}; 

template<typename T> 
struct has_single_f<T, decltype(proto(&T::f))>: std::true_type {}; 

//... 

int main() { 
    static_assert(not has_single_f<S>::value, "!"); 
    static_assert(has_single_f<U>::value, "!"); 
} 
+1

我開始覺得用模板:)沒有什麼是不可能的。很好的答案! – xinaiz

+0

@BlackMoses不客氣。這是棘手的,很好的問題。 – skypjack

相關問題