2016-03-01 32 views
0

以下是我編寫的用於在CRTP設置中試驗追溯返回類型的模型代碼。使用CRTP時的追溯返回類型使用

#include <iostream> 
#include <memory> 
#include <utility> 

using namespace std; 

struct t_aspect{ 
    struct t_param1 {}; 
}; 

// Generic Selector 
template <typename t_detail> 
struct Select; 

template <> 
struct Select<t_aspect::t_param1> { 
    using typeof = t_aspect::t_param1; 
}; 

//Base CRTP class 
template<typename dclas> 
class CrtpB 
{ 
    public: 
     template<typename T1> 
     auto func1() -> // What should be here? 
     { 
      return(static_cast<dclas*>(this)->func1<T1>()); 
     } 
}; 


//Derived CRTP class 
class CrtpD : public CrtpB<CrtpD> 
{ 
    private: 
     uint32_t param1 = 0; 

    private: 
     auto func1(const t_aspect::t_param1&) -> uint32_t 
     { 
      return(param1); 
     } 

    public: 
     static auto create() -> unique_ptr<CrtpB> 
     { 
      return(unique_ptr<CrtpD>(new CrtpD)); 
     } 

     template<typename T1> 
     auto func1() -> decltype(func1(typename Select<T1>::typeof())) 
     { 
      return(func1(typename Select<T1>::typeof())); 
     } 
}; 


int main() 
{ 
    auto crtp = CrtpD::create(); 
    auto parm = crtp->func1<t_aspect::t_param1>(); 
    return 0; 
} 

我想破譯應該是什麼在CrtpB的FUNC1的尾隨返回類型一定的幫助。

我一直在使用

decltype(static_cast<dclas*>(this)->func1<T1>()) 

嘗試,但這個不起作用。我也嘗試了基於Inferring return type of templated member functions in CRTP中找到的解決方案編寫幫助函數。

template <typename D, typename T> 
struct Helpr { 
    typedef decltype(static_cast<D*>(0)->func1<T>()) type; 
}; 

但是這也行不通。

回答

1

dclas當基類實例化時是不完整的類型。你需要做兩件事情,使這項工作:

  • 推遲func1<T1>()類型的檢查,直到種類齊全
  • 使用template關鍵字的依賴性表達這樣模版定義是正確的解析:

我們可以通過增加間接層做到這一點:

namespace detail { 
    template <class T, class Func1Arg> 
    struct func1_t { 
     using type = decltype(std::declval<T>().template func1<Func1Arg>()); 
    }; 
}; 

然後你使用這個特質作爲追蹤返回類型:

template<typename T1> 
auto func1() -> typename detail::func1_t<dclas,T1>::type 
{ 
    return(static_cast<dclas*>(this)->template func1<T1>()); 
} 
+0

的確可以解決我的問題。謝謝。 – vixiv

+0

當我使用http://coliru.stacked-crooked.com中的修復程序編譯代碼時,代碼會編譯。我在我的機器上試過了,並且出現以下錯誤: snip1.cpp:33:34:error:static_cast from'CrtpB *'to'CrtpD *',它們與繼承無關,不允許 auto func2() - > decltype(static_cast (this) - > template func2 ()) 你知道可能是什麼問題嗎? – vixiv

+0

@TartanLlama,我嘗試了你之前的建議,但似乎沒有幫助。現在錯誤是: snip1.cpp:34:62:錯誤:沒有名爲在 'CrtpD' 汽車FUNC2 'FUNC2' 構件() - > decltype(declval () - >模板FUNC2 ()) – vixiv