2016-04-01 10 views
1

コンパイル時にジャンプテーブルを作成し、実行時に使用するという考えで試しています。この場合、constexprデータ配列に任意のデータを格納

struct blah { constexpr blah() {} int operator()() const { return 42; }}; 
int fun(std::string const& str) 
{ 
    return switch_ { 
     case_{ "hello"_s, [](){ return 5; } 
     case_{ "blah"_s, blah{} } 
    }(str); 
} 

_sconstexpr stringです:それはそうのようなものを働くだろう。

これは、constexprハッシュ関数を使用してコンパイル時にハッシュテーブルを作成するという考えです。

私は例外を除いてすべての問題を解決していると思いますが、解決できない場合は実装できない可能性があります。それは初期化です。

ハッシュは配列で実装されます。衝突は、その配列内の空のセルに配置されます。したがって、私は、すべてのデータ型を単一の型として格納する方法を見つける必要があります。基本的なタイプの消去技術は動作していないようです。また、配置newを使用したり、値をバイトにキャストして配列にコピーすることはできません。また、一般に実行時に動作するが、constexprコンテキストでは許可されないユニオントリックを呼び出すUBを使用しようとしました。

利用できるように思われる唯一のオプションは、実際にはタプルのようなソートの組み合わせをレンダリングすることです。したがって、1つの値しか格納しませんが、ハッシュのすべての型のメモリを占有します。これは私には良くないようです。

誰かがconstexprで生成された配列に任意の型を格納する方法を考えることができますか?

+0

私は、少なくとも私の狂った脳で、解決しようとしている問題を解決したと思います。私が実装を取得すると、私は投稿します。あなたがそれを見て興味がある場合は、こちらをご覧ください:https://github.com/crazy-eddie/experiments/constexpr-datastructures。まだインポートされていないのでリンクは失敗しますが、それが終わるところです。 –

+0

https://github.com/crazy-eddie/experiments/tree/master/constexpr-datastructures –

答えて

0

あなたの問題を解決する一般的な方法はないと思います。しかし、文字列リテラルの場合は最近、パラメータとしてテンプレートクラスに渡す(完全ではない)方法を提案しました。それはhereです。

これを使用すると、文字列リテラルによってインデックスされた種類の配列を作成できます。プログラムの

#include <iostream> 
#include <functional> 

#include "string_literal.h" 

template <class SLiteral> 
struct switch_; 

template <> 
struct switch_<STRING_LITERAL(3, "abc")> { 
    int do_something() { return 1; } 
}; 

template <> 
struct switch_<STRING_LITERAL(12, "123456789012")> { 
    int do_something() { return [](){ return 5;}(); } 
}; 

template <> 
struct switch_<STRING_LITERAL(8, "blahblah")> { 
    std::function<int()> foo; 
    template <class T> 
    switch_(T t) { 
     foo = t; 
    } 
    int do_something() { return foo(); } 
}; 

int main() { 
    std::cout << switch_<STRING_LITERAL(3, "abc")>().do_something() << std::endl; 
    std::cout << switch_<STRING_LITERAL(12, "123456789012")>().do_something() << std::endl; 
    std::cout << switch_<STRING_LITERAL(8, "blahblah")>([](){return 10;}).do_something() << std::endl; 
} 

出力は次のとおりです:専門によって

1 
5 
10 
+0

私は解決策を絞っています。私のOPへのコメントを見てください。 –

+0

@CrazyEddieあなたのコードを調べました。あなたの質問と擬似コードを読んだ後、constexpr型の配列ではなく、constexprマップ(任意のconstexpr型で索引付けされた)を実装したいという印象を得ました。申し訳ありませんが、私はあなたの質問を誤解しています... –

関連する問題