2016-07-18 40 views
-1

時會被調用,其被重載用於用戶定義類型X如下自由函數fooC作爲一個庫類型的主叫foo):確定我使用的過載傳遞類型作爲參考

template <typename C> 
void foo(C&, const X&) {...} 

我能夠確定在編譯時是否存在用於特定類型X過載:

template <typename... Args> 
auto foo_exists(int) -> decltype(std::bind<void(*)(Args...)>(&foo, std::declval<Args>()...), std::true_type()); 

template <typename... Args> 
auto foo_exists(char) -> std::false_type; 

struct Caller 
{ 
    template <typename T> 
    void call(const T& x) 
    { 
     static_assert(decltype(foo_exists<decltype(*this), const T&>(0))::value, ""); 
    } 
}; 

現在假設下面的類層次結構與foo個重載BaseDerived

struct Base{}; 
struct Derived : Base {}; 
struct Leaf : Derived{}; 

template <typename C> 
void foo(C&, const Base&) { std::cout << "Base" << std::endl; } 

template <typename C> 
void foo(C&, const Derived&) { std::cout << "Derived" << std::endl; } 

我如何能夠確定調用foo(..., Leaf())時,該const Derived&超載將被調用?

一般地講:

我想,以找出是否一個函數重載爲特定類型的X測試所需的確切類型的foo。存在;如果它不存在,我想知道是否存在基類型爲X的其他函數重載,如果存在,則在將類型爲const X&的參數傳遞給它時調用哪個函數。

「哪些」信息應包含基本類型,對於上述示例應爲Derived(而不是Base)。

live example

+0

@ildjarn我讀了另外一個問題,但是我想也許我對基類重載的限制會啓用我需要的東西 –

+0

最基本的限制是缺少編譯時反編譯的重載集;用作參數的類型沒有軸承AFAICT。 – ildjarn

回答

0

可以複製的函數簽名和寫一個自定義特徵,以檢測其中的一個將被調用,像這樣:

template <typename T> 
struct S { 
    static Base mock_foo(const Base&); 
    static Derived mock_foo(const Derived&); 
    static void mock_foo(...); 

    // Base if Base overload will be called, Derived if Derived overload 
    // will be called, void if neither 
    using type = decltype(mock_foo(std::declval<T>())); 
}; 

http://coliru.stacked-crooked.com/a/b72655b770becc15

我不知道如果可以「自動」執行此操作,則可以使用,而無需以此方式輸入自定義特徵。我猜測答案是否定的,這需要核心語言中的某種反思支持。

+0

不幸的是我不能枚舉我的庫中的所有簽名,因爲'foo'的重載是用戶定義的 –

+0

@ m.s。我懷疑在沒有語言支持的情況下實現這樣的特質是可能的。但讓我們看看是否有人證明我錯了。 – Brian

+0

我擔心你是對的,看到這個問題:http://stackoverflow.com/questions/35561453/determining-which-overload-was-selected我想也許我對基類重載的限制可以使這個 –