學習C++模板元編程(2)

來源:互聯網
上載者:User
 

再看一道簡單一些的習題:寫一個三個參數的元函數replace_type<c, x, y>,其中第一個參數c為任意的組合類別型,該元函數將c中出現的所有x類型以y類型替換掉。例如:
typedef replace_type< void*, void, int >::type t1; // int*
 
typedef replace_type<int const*[10], int const, long>::type t2; // long* [10]
 
typedef replace_type<char& (*)(char&), char&, long&>::type t3; // long& (*)(long&)
 
為簡單起見,可以假設c如果是函數類型的話,其參數數量不超過2個。我的想法是這樣的,replace_type<c, x, y>模板以c = x為條件進行偏特化,主模板就符合c != x的條件,把它轉為另一個元函數replace_type_d<c, x, y>;再將replace_type_d<>按c的類型(分為引用、指標、CV限定、數組、函數等)進行偏特化,遞迴調用replace_type<>。replace_type<>部分的程式如下:
#include <iostream>#include "boost/type_traits/is_same.hpp" template <typename C, typename X, typename Y>struct replace_type_d; template <typename C, typename X, typename Y>struct replace_type : replace_type_d<C, X, Y>{}; template <typename X, typename Y>struct replace_type<X, X, Y>{    typedef Y type;}; 
這一段代碼先給出replace_type_d<>的聲明,然後定義replace_type<>的主模板,使用元函數前轉(metafunction forwarding)的方法,直接調用replace_type_d<>。最後是c = x的replace_type<>的偏特化模板,由於c = x,所以結果是直接返回y類型。replace_type_d<>部分的程式如下:
template <typename C, typename X, typename Y>struct replace_type_d{    typedef C type;}; template <typename C, typename X, typename Y>struct replace_type_d<C&, X, Y>{    typedef typename replace_type<C, X, Y>::type& type;}; template <typename C, typename X, typename Y>struct replace_type_d<C*, X, Y>{    typedef typename replace_type<C, X, Y>::type* type;}; template <typename C, typename X, typename Y>struct replace_type_d<C const, X, Y>{    typedef typename replace_type<C, X, Y>::type const type;}; template <typename C, typename X, typename Y>struct replace_type_d<C volatile, X, Y>{    typedef typename replace_type<C, X, Y>::type volatile type;}; template <typename C, typename X, typename Y, std::size_t n>struct replace_type_d<C[n], X, Y>{    typedef typename replace_type<C, X, Y>::type type[n];}; template <typename R, typename X, typename Y>struct replace_type_d<R(*)(), X, Y>{    typedef typename replace_type<R, X, Y>::type RetType;    typedef RetType (*type)();}; template <typename R, typename A, typename X, typename Y>struct replace_type_d<R(*)(A), X, Y>{    typedef typename replace_type<R, X, Y>::type RetType;    typedef typename replace_type<A, X, Y>::type ArgType;    typedef RetType (*type)(ArgType);}; template <typename R, typename A1, typename A2, typename X, typename Y>struct replace_type_d<R(*)(A1, A2), X, Y>{    typedef typename replace_type<R, X, Y>::type RetType;    typedef typename replace_type<A1, X, Y>::type Arg1Type;    typedef typename replace_type<A2, X, Y>::type Arg2Type;    typedef RetType (*type)(Arg1Type, Arg2Type);}; 
這一段代碼首先是replace_type_d<>的主模板,直接返回c類型。接下來是replace_type_d<>的8個偏特化版本,分別對應c的各種類型:引用、指標、const限定、volatile限定、數組、無參函數、一元函數、二元函數。由於題目假定如果c為函數類型,其參數數量不超過2個,因此最多隻涉及到二元函數。每個偏特化版本都非常相似,針對不同的情況對c進行分解,然後分別對分解後的類型遞迴調用replace_type<>來獲得替換結果,再對替換結果進行組合,得到最終的結果。如:對於參考型別,分解出被參考型別,對其調用replace_type<>獲得中間替換結果,再加上引用,就得到最終替換結果。又比如:對於一元函數類型,分解出函數傳回型別及參數類型,分別對它們調用replace_type<>獲得兩個中間替換結果,再用這兩個中間結果組合成一元函數,就得到最終替換結果。最後是測試用的main()及運行結果,如下:
int main(){    typedef replace_type<void*, void, int>::type t1;    std::cout << boost::is_same<t1, int*>::value << std::endl;    typedef replace_type<int const*[10], int const, long>::type t2;         std::cout << boost::is_same<t2, long*[10]>::value << std::endl;    typedef replace_type<char&(*)(char&), char&, long&>::type t3;    std::cout << boost::is_same<t3, long&(*)(long&)>::value << std::endl;    return 0;} Output:111 
輸出的三個1代表了三個true,即替換後的結果與預期結果全部相符。 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.