2016-07-07 12 views
0

ビデオで次のコードが見つかりました。テンプレートメタプログラミングでカスタムタイプを定義する

#include <iostream> 

using namespace std; 

#define LIST1(T1) Node<T1,Null> 
#define LIST2(T1,T2) Node<T1,LIST1(T2)> 
#define LIST3(T1,T2,T3) Node<T1,LIST2(T2,T3)> 
#define LIST4(T1,T2,T3,T4) Node<T1,LIST3(T2,T3,T4)> 

struct Null { }; 
template <int X, typename Next> 
struct Node { 
    static const int val = X; 
    typedef Next Next_; 
}; 

template <typename List> 
struct Sum 
{ 
    static const int sum = List::val + Sum<typename List::Next_>::sum; 
}; 

template <> 
struct Sum<Null> { 
    static const int sum = 0; 
}; 

int main() 
{ 
    cout << Sum<LIST4(2, 2, 3, 4)>::sum << endl; 
} 

私の質問は、これを行うにはどうすればよいですか?同じような種類の解析を他にどのように行う必要がありますか?私が見る主な問題は、型を定義するために使用されるプリプロセッサディレクティブです。そうする他の方法はありますか?入力を解析します

Sum<IP<120.100.10.20>> 

は例えば、私は上記と同じIPアドレスを表現したいです。

また、ファイルから取り出すことができる場合は、はるかに便利です。私は、この種の書式設定されたデータはTMPの型として取られるべきだと思います。どのように私はそれをサポートするコードを変更するだろうか?

を編集する:他のコードを追加すると便利だと思うようになります。私の質問がある

#include <iostream> 
#define LIST1(T1) Node<T1,Null> 
#define LIST2(T1,T2) Node<T1,LIST1(T2)> 
#define LIST3(T1,T2,T3) Node<T1,LIST2(T2,T3)> 
#define LIST4(T1,T2,T3,T4) Node<T1,LIST3(T2,T3,T4)> 

using namespace std; 

// Highest bit in an IP address 
template <typename List, int N, bool B> 
struct highestBitSet 
{ 
    static const bool b = List::val & (1 << N); 
    static const int bit = highestBitSet<List, N - 1, b>::bit; 
}; 

template <typename List, int N> 
struct highestBitSet<List,N,true> 
{ 
    static const int bit = N+1; 
}; 

template <typename List> 
struct highestBitSet<List, -1, false> 
{ 
    static const int bit = 8+highestBitSet<List::Next_, 7, false>::bit; 
}; 

template <int X> 
struct highestBitSet<Null, X, false> 
{ 
    static const int bit = 0; 
}; 


int main() 
{ 
    // Will print 0 
    cout << highestBitSet<LIST4(1, 0, 0, 0), 7, false>::bit << endl; 
    // WIll print 31 
    cout << highestBitSet<LIST4(0, 0, 0, 255), 7, false>::bit << endl; 
    return 0; 
} 
+2

これは、可変的なテンプレートパラメータリストのための貧しい人の(C++ 98のバウンド)ソリューションのようです。現在の10年へようこそ。 –

+0

@πάνταῥεῖ実際、これはAndrei AlexandrescuがModern C++ Designのbookでタイプリストを扱っているのと同じように見えます。 – user2296177

+0

@πάνταῥεῖ申し訳ありません私は古い思考や新しい実装に精通していません。私を案内してもらえますか? –

答えて

3

、それを行うには良い方法は何ですか?同じような種類の解析を他にどのように行う必要がありますか?私が見る主な問題は、型を定義するために使用されるプリプロセッサディレクティブです。そうする他の方法はありますか? C++ 17利用できない場合はC++ 17の折り畳み式を使用して、またはC++ 14 constexpr

:たとえば

#include <iostream> 

template<int... N> int_list { }; 

template<int... N> int_list<N...> list() { return {}; } 

template<int... N> 
int sum(int_list<N...>) 
{ 
#if __cplusplus > 201402L 
    return (N + ...); 
#else 
    const int vals[] = { N... }; 
    int sum = 0; 
    for (auto v : vals) 
    sum += v; 
    return sum; 
#endif 
} 

int main() 
{ 
    std::cout << sum(list<2, 2, 3, 4>()) << std::endl; 
} 

を、私は上記と同じIPアドレスを表現したいです。

Sum<IP<120.100.10.20>> 

入力を解析します。

IPv4アドレスには可変長リストは必要ありません。常に4つのコンポーネントがあります。そしてあなたが示したコードは解析をしません。それはまったく別の問題です。別の4つの引数をLIST4(120, 100, 10, 20)のようなマクロまたは関数に渡すことは、有効なC++トークンでさえもない120.100.10.20の記述とはまったく異なります。

また、ファイルから取り出すことができる場合は、はるかに役立ちます。私は、この種の書式設定されたデータはTMPの型として取られるべきだと思います。どのように私はそれをサポートするコードを変更するだろうか?

ファイルからデータを読み取ることは実行時の効果です。テンプレート(コンパイル時)とI/O(実行時)を組み合わせることはできません。

+0

これは本当に面白いです。また、リストの値をファイルから読み込むことができるかどうかを教えてください。私はファイルのIPのリストを持っているように私はTMPにフィードするためにそれらを使用したい。出来ますか? –

+0

私は既にそれに答えました。 –

+0

ジョナサン、ありがとう、 –

関連する問題