在嘗試實作現有 API 的新 API 替代方案時,我無法找到適當的解決方案,我仍然希望支持向后兼容性;
讓它成為我的舊 API:
typedef int[3] Node;
template <class T>
struct convert{
static std::pair<bool, T> decode(Node node);
}
//and a call to this construct here
template<typename T>
T decode_for_me(Node node) {
return convert<T>::decode(node).second;
}
//with a specialization, for example a custom type
struct custom_type {int a; int b;};
template<>
struct convert<custom_type>{
static std::pair<bool, custom_type> decode(Node node) {
custom_type c; c.a=node[0]; c.b=node[1]; return std::make_pair(true, c); };
};
int main() {
Node node = {1,2};
decode_for_me<custom_type>(node);
return 0;
}
現在想將 convert::decode 更改為更苗條的簽名并重繪 API 以實作更多型別:
class alt_type {
int x; int y; int z;
alt_type(int x, int y, int z) : x(x), y(y), z(z) {};
}
template<>
struct convert<alt_type>{
static alt_type decode_new_api(Node node) {return {node[0], node[1], node[2]};};
}
我現在將如何在類布局/特征上實作條件開關convert<T>以選擇正確的呼叫路徑,替換decode_for_me<T>()為:
template<typename T>
T decode_for_me(Node node) {
if constexpr ( "has_trait<convert<T>, "decode">" ) //<<<<
return convert<T>::decode(node).second;
if constexpr ( "has_trait<convert<T>, "decode_new_api">" ) // <<<<
return convert<T>::decode_new_api(node);
throw std::runtime_error();
}
我在 SFINAE 中研究了一些類似的問題和答案,這些問題和答案從模板構造到使用decltype和declval. 但是,所有這些都處理成員函式,而在這里我對靜態評估感興趣。我也不能讓他們中的任何一個為我作業。
謝謝你的幫助!
uj5u.com熱心網友回復:
我不知道用一個接收方法名稱(decode 或 decode_new_api)作為引數的單一型別特征來解決這個問題的方法。
但是,如果您接受針對不同方法的不同測驗,一個可能的解決方案是使用幾個宣告(無需定義)函式來測驗“宣告”
template <typename>
std::false_type has_decode (long);
template <typename T>
auto has_decode (int)
-> decltype( T::decode(std::declval<Node>()), std::true_type{});
和一對“declare_new_api”
template <typename>
std::false_type has_decode_new_api (long);
template <typename T>
auto has_decode_new_api (int)
-> decltype( T::decode_new_api(std::declval<Node>()), std::true_type{});
現在你decode_for_me()成為
template <typename T>
T decode_for_me(Node node) {
if constexpr ( decltype(has_decode<convert<T>>(0))::value )
return convert<T>::decode(node).second;
if constexpr ( decltype(has_decode_new_api<convert<T>>(0))::value )
return convert<T>::decode_new_api(node);
throw std::runtime_error("no decode");
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/436771.html
