2012-02-25 60 views
2

我有一組專門的模板。現在我想爲兩種情況創建專門的模板:檢測模板化方法和自由函數的存在

  1. 如果某個方法存在於類/結構中(檢測到名稱就夠了)。

  2. 如果存在某個自由功能(在這種情況下應該檢測到名稱和部分簽名)。

問題是,自由函數和類方法都將被模板化。這是針對一種序列化體系結構,並且我有多種序列化方法,所以方法/函數的模板參數將是專門的其他模板提供的序列化策略。我不能讓策略成爲抽象的基礎,因爲後來其他的模板化方法將被調用,虛擬和模板不會混合。

這裏是什麼,我需要一個例子:

template<typename T> 
struct strategy1 {}; 

template<> 
struct strategy1<char> { 
    void call() { 
    // Do char specific stuff 
    } 
}; 

class foo_specialized { 
/* ... */ 
}; 

template<> 
struct strategy1<foo_specialized> { 
    void call() { 
    // do foo_specialized stuff 
    } 
}; 

class foo_method { 
public: 
    template< Typename T> 
    void serialize(T & t) { 
    // use T here to do stuff 
    } 
}; 

/* This should be used for foo_method */ 
template< typename T > 
struct strategy1</* don't know what to put here */> 
    struct strategy1_helper{ 
    template<typename T2> 
    void call(T2 t) { 
     // do stuff with t 
    } 
    }; 

    void call(const T & t) { 
    t.serialize(strategy1_helper()); 
    } 
}; 

class foo_function { 
/* ... */ 
}; 

template<typename T> 
void serialize(const foo_function & foo, T & t) { 
    // use T here 
} 

/* This should be used for foo_function */ 
template< typename T > 
struct strategy1</* don't know what to put here */> 
    struct strategy1_helper{ 
    template<typename T2> 
    void call(T2 t) { 
     // do stuff with t 
    } 
    }; 

    void call(const T & t) { 
    serialize(t, strategy1_helper()); 
    } 
}; 

是它在某種程度上可能有模板解決機制選擇根據實際提供的參數這兩個最後的專業化?還是有一個更清潔的設計來實現這一目標?

我可以很容易地使用C++ 11提供的類型特徵和元編程功能,所以我不需要自己完成SFINAE步驟。

+0

雖然我無法直接回答,但'boost :: serialization'正在使用ADL來使用類方法或成員函數來(去)序列化給定的類。它沒有提供序列化策略的選項,但它專門針對不同的輸出格式。你也許可以使用它的想法,因爲你的「戰略」將在彙編時知道。 – eudoxos 2012-02-25 12:47:10

+1

請注意,由於重載(並且函數模板通常會自行重載),因此單獨檢測名稱比檢測給定簽名的名稱更困難。 – 2012-02-26 01:31:05

回答

2

解決方案需要使用SFINAE來檢測所述成員函數的潛在返回類型。該技巧在訪問會員指針失敗的情況下使用省略號的超載。

正確的實現也需要一些宏模板。我有這樣躺在這裏的實現:

https://github.com/jfalcou/boosties/tree/master/introspection/boost

現在思考的C++ 11的方式,一些這當然可以變成基於decltype檢測,但仍然需要宏觀,你需要一種方法來提取成員名稱。