2017-04-26 10 views
2

私はこの記事に出くわした: Convert a number to a string literal with constexprVariadicテンプレートの継承を解釈する方法は?

そして、答えは非常に興味深いです:

namespace detail 
{ 
    template<unsigned... digits> 
    struct to_chars { static const char value[]; }; 

    template<unsigned... digits> 
    const char to_chars<digits...>::value[] = {('0' + digits)..., 0}; 

    template<unsigned rem, unsigned... digits> 
    struct explode : explode<rem/10, rem % 10, digits...> {}; 

    template<unsigned... digits> 
    struct explode<0, digits...> : to_chars<digits...> {}; 
} 

template<unsigned num> 
struct num_to_string : detail::explode<num> {}; 

私の質問は以下のとおりです。

  1. "構造体の爆発:爆発" 爆発から継承を爆発宣言します;どのように "構造体の分解< 0、数字...>:to_chars"?

  2. 最初のテンプレートパラメータとして '0'の機能は何ですか?

ありがとう!

答えて

6

これは、終了条件として機能する部分的な特殊化を伴う再帰式です。

explode<12, 3, 4>  // 123/10 = 12, 123 % 10 = 3 

継承から:

:から

explode<1, 2, 3, 4>  // 12/10 = 1, 12 % 10 = 2 

継承から

explode<123, 4>   // 1234/10 = 123, 1234 % 10 = 4 

継承:から

explode<1234> 

継承この時点で、(原発テンプレートのremと称する)一番左の値が

explode<0, 1, 2, 3, 4> // 1/10 = 0, 1 % 10 = 1 

であるので、部分的な特殊一致:整数をになったことを示す

template <unsigned... digits> 
struct explode<0, digits...> : to_chars<digits...> {}; 

を(結局から継承別桁):最後

to_chars<1, 2, 3, 4> 

は、to_charsはまたように、文字に数字を回し、char配列にパラメータパックを拡張します12'2'なり、'1'となり、そのために:それは文字列であるかのようvalueを扱うことができるように

ここ
const char to_chars<1, 2, 3, 4>::value[] = { '1', '2', '3', '4', 0 }; 

0は、ヌル終端文字です。

+0

バリディアックテンプレートの拡張によって派生することを継承し、最後に別の構造体(継承)を継承することは非常に面白いです。ありがとう! – Hei