2017-07-14 98 views
2

請考慮以下情況,我想檢查我傳遞給其他某個函數的類型sf是否具有sf所需的成員函數T::mf,我知道返回類型和名稱,但可以有任何數量的重載。檢查類型T是否有任何超載的成員函數,SFINAE

經過一些修補(好吧很有趣..)和谷歌搜索,我可以得到像下面的代碼工作,問題是我不知道如何表示print可以有可變數量的參數。

#include <type_traits> 
#include <utility> 


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

template <typename T> 
struct has_write<T, decltype(std::declval<T>().write())> : std::true_type {}; 


template <typename T, typename R = void , typename ...Args> 
struct has_print : std::false_type {}; 

// cant deduce, specialization never used 
template <typename T, typename ...Args> 
struct has_print<T, decltype(std::declval<T>().print(std::declval<Args>()...))> : std::true_type {}; 


struct Foo { 
    void write(); 
}; 

struct Bar { 
    int print(int, float, int); 
}; 

int main(){ 
    static_assert(has_write<Foo>::value, "Does not have write.."); 
    static_assert(has_print<Bar>::value, "Does not have print.."); 
    return 0; 
} 

以上編譯與g++但第二assert失敗,clang是一個比較有用的,並告訴我,對於has_print的特將永遠不會被使用,因爲它不能推斷出所有類型。

+1

AFAIK這樣做的唯一方法是嘗試使用可以隱式轉換爲任何類型的0..N實例調用print。反思應該會使這更容易... –

+1

好吧,因爲你的'sf'函數會調用一個特定版本的'print',它具有該函數已知的特定數量的參數,所以你可以檢查具有已知的具體'has_print'類型。 – SergeyA

+0

我認爲,但我是新來的,爲了學習,想知道一種乾淨的方式(假裝這不是一個xy問題),找到一個類型是否有任何重載。 – arynaq

回答

2

由於您將在sf函數中調用您的過載,因此您應該使用函數將調用它的類型檢查特定超載的可用性。

常規檢查的可用性的類中的任何過載將始終是通過定義一個XY的問題,因爲任何超載可用性是永遠重要。你需要知道你可以用一組給定的參數來調用一個名字。考慮到這一點:要求給定名稱的任何過載的可用性在概念上與詢問特定類是否具有任何方法完全相同。顯然你不會對它感興趣?

相關問題