タグ付けされた質問 「template-meta-programming」

27
クラスメンバー関数の存在のテンプレートチェック?
クラスで特定のメンバー関数が定義されているかどうかに応じて動作を変更するテンプレートを作成することは可能ですか? これが私が書きたいことの簡単な例です: template<class T> std::string optionalToString(T* obj) { if (FUNCTION_EXISTS(T->toString)) return obj->toString(); else return "toString not defined"; } したがって、定義されclass Tている場合はtoString()、それを使用します。そうでなければ、それはしません。方法がわからない魔法の部分は、「FUNCTION_EXISTS」部分です。

20
std :: tupleの要素をどのように反復できますか?
(C ++ 11を使用して)タプルをどのように反復できますか?私は以下を試しました: for(int i=0; i<std::tuple_size<T...>::value; ++i) std::get<i>(my_tuple).do_sth(); しかし、これは機能しません: エラー1:申し訳ありませんが、実装されていません:「リスナー...」を固定長の引数リストに展開できません。 エラー2:定数式では使用できません。 では、タプルの要素を正しく反復するにはどうすればよいですか?


1
より多くの精神の狂気-パーサータイプ(ルールとint_parser <>)およびメタプログラミング技術
質問は下部に太字で示されています。問題は、最後に向かって蒸留コードフラグメントによっても要約されています。 私は自分の型システム(型システムが型から文字列へと行き来する)を単一のコンポーネント(Lakosによって定義されている)に統合しようとしています。私が使用していますboost::array、boost::variantと、boost::mplこれを達成するために、。タイプのパーサーとジェネレーターのルールをバリアントに統合したいと思います。未定義のタイプ、int4(以下を参照)タイプ、およびint8タイプがあります。バリアントはとして読み取りますvariant&lt;undefined, int4,int8&gt;。 int4特性: struct rbl_int4_parser_rule_definition { typedef boost::spirit::qi::rule&lt;std::string::iterator, rbl_int4()&gt; rule_type; boost::spirit::qi::int_parser&lt;rbl_int4&gt; parser_int32_t; rule_type rule; rbl_int4_parser_rule_definition() { rule.name("rbl int4 rule"); rule = parser_int32_t; } }; template&lt;&gt; struct rbl_type_parser_rule&lt;rbl_int4&gt; { typedef rbl_int4_parser_rule_definition string_parser; }; 上記のバリアントは未定義として開始され、次にルールを初期化します。問題が発生し、50ページのエラーが発生しましたが、最終的に追跡できました。バリアントはoperator=割り当て中に使用し、別のバリアントに割り当てるboost::spirit::qi::int_parser&lt;&gt;ことはできません(operator =)。 対照的に、未定義のタイプには問題はありません。 struct rbl_undefined_parser_rule_definition { typedef boost::spirit::qi::rule&lt;std::string::iterator, void()&gt; rule_type; rule_type rule; rbl_undefined_parser_rule_definition() { rule.name("undefined parse rule"); …

3
コンパイル時に多次元std :: vectorの深さを取得するにはどうすればよいですか?
多次元を取りstd::vector、深さ(または次元数)をテンプレートパラメーターとして渡す必要がある関数があります。この値をハードコーディングする代わりに、を使用して深さを値として返すconstexpr関数を作成します。std::vectorunsigned integer 例えば: std::vector&lt;std::vector&lt;std::vector&lt;int&gt;&gt;&gt; v = { { { 0, 1}, { 2, 3 } }, { { 4, 5}, { 6, 7 } }, }; // Returns 3 size_t depth = GetDepth(v); この深さはテンプレート関数としてテンプレート関数に渡されるため、コンパイル時にこれを行う必要があります。 // Same as calling foo&lt;3&gt;(v); foo&lt;GetDepth(v)&gt;(v); これを行う方法はありますか?

4
テンプレートメタプログラミング
誰かが最初のテンプレートのメタプログラミング方法が無限ループになる理由を私に説明できますが、2番目の方法は正しく実行されます。 #include &lt;iostream&gt; using namespace std; template&lt;int N, int M&gt; struct commondivs { static const int val = (N&lt;M) ? commondivs&lt;N,(M-N)&gt;::val : commondivs&lt;(N-M),M&gt;::val; }; template&lt;int N&gt; struct commondivs&lt;N,N&gt; { static const int val = N; }; int commondiv(int N, int M){ if(N==M){ return N; } return (N&lt;M)?commondiv(N,(M-N)):commondiv((N-M),M); } int main() …

2
コンセプトを関数に渡す
概念はコンパイル時の述語として定義されているため、これらの述語をコンパイル時のアルゴリズムに実際に再利用することもできますか?たとえば、タプルのすべての型がコンセプトに準拠しているかどうかを確認することは可能でしょうか?私が見た限りでは、概念を関数に渡すことは決して不可能であり、そのため、これらの場合にテンプレートを使用することに戻ってきました。 #include &lt;type_traits&gt; template&lt;typename T&gt; concept FloatLike = std::is_same_v&lt;T, float&gt;; struct IsFloat { template&lt;typename U&gt; constexpr static bool test() { return FloatLike&lt;U&gt;; } }; template&lt;typename Predicate, typename... T&gt; constexpr bool all_types() { return (Predicate::template test&lt;T&gt;() &amp;&amp; ...); } int main() { static_assert(all_types&lt;IsFloat, float, float&gt;()); static_assert(!all_types&lt;IsFloat, float, int&gt;()); } 私がやりたいのは次のようなものなので、それを使用できるようにするために常にコンセプトをラップする必要はありません。 template&lt;concept …

1
constexprコンストラクターで配列を初期化することは正当ですか?
次のコードは正当ですか? template &lt;int N&gt; class foo { public: constexpr foo() { for (int i = 0; i &lt; N; ++i) { v_[i] = i; } } private: int v_[N]; }; constexpr foo&lt;5&gt; bar; Clangはそれを受け入れますが、GCCとMSVCはそれを拒否します。 GCCのエラーは次のとおりです。 main.cpp:15:18: error: 'constexpr foo&lt;N&gt;::foo() [with int N = 5]' called in a constant expression 15 …

1
オーバーロードされた関数ポインターとその引数を渡す際の不正な型の推定
std::invoke関数がオーバーロードされている場合でも、関数タイプを推定する作業を行うためのラッパーを提供しようとしています。 (私は昨日、可変およびメソッドポインターバージョンについて関連する質問をしました)。 関数に1つの引数がある場合、このコード(C ++ 17)は通常の過負荷状態で期待どおりに機能します。 #include &lt;functional&gt; template &lt;typename ReturnType, typename ... Args&gt; using FunctionType = ReturnType (*)(Args...); template &lt;typename S, typename T&gt; auto Invoke (FunctionType&lt;S, T&gt; func, T arg) { return std::invoke(func, arg); } template &lt;typename S, typename T&gt; auto Invoke (FunctionType&lt;S, T&amp;&gt; func, T &amp; arg) { return …

7
C ++で再帰的に整数のテンプレートパラメーターを一致させることは可能ですか?
次の問題があります。N次元ベクトルを次のように定義します #include &lt;vector&gt; #include &lt;utility&gt; #include &lt;string&gt; template &lt;int N, typename T&gt; struct NVector{ typedef std::vector&lt;typename NVector&lt;N-1,T&gt;::type&gt; type; }; template &lt;typename T&gt; struct NVector&lt;1,T&gt; { typedef std::vector&lt;T&gt; type; }; ネストされたベクトルのリーフ要素をいくら深くても変換でき、同じ形状の新しいネストされたベクトルを返す、より高次の関数マップを書きたいと思います。私が試してみました template &lt;int N, typename T, typename Mapper&gt; struct MapResult { typedef decltype ( (std::declval&lt;Mapper&gt;()) (std::declval&lt;T&gt;()) ) basic_type; typedef typename NVector&lt;N, …

4
C ++メタプログラミングですべてのテンプレートを使用していますか?
私はメタプログラミングが一般的であり、特にそれがC ++で何であるかを理解しようとしています。c ++メタプログラミングを検索すると、テンプレートメタプログラミング(TMP)のチュートリアルは表示されますが、テンプレートの特定の使用法またはテンプレートのすべての使用法のみが分類されているかどうかの説明はありません。 私の質問は、C ++でのテンプレートのすべての使用がメタプログラミングとして分類されるかどうかです。それがなぜなのか、そうでないのかについての説明も役に立ちます。ありがとうございました。

1
時間テキストをコンパイルして数値変換する(atoi)
コンパイル時にatoi()関数を実装したい(C ++ 11またはC ++ 14標準を使用して、C ++言語で)。したがって、二重引用符で囲まれたテキストを数値として解析したり、エラーを再現したりできます。より具体的には、それはコンパイル時にprintfのような形式を解析できるより大きなシステムの一部です。そして、私は単語のフォーマット文字列を分割し、特定の単語を数字で表すことができる場合は、文字列ではなく番号を出力します(シーンの背後にあるシリアライザクラスは、文字列よりも数値をより効率的にシリアル化できます。重要なのは、デシリアライザはすべての文字列を数値として解析しようとしないことです。これは、フォーマット文字列内に出力されるすべての数値は常に数値として表現され、文字列としては表現されないためです...) 私が2つ知っているように、タスクを解決するには2つの方法があります。 1)constexpr関数を使用する。 2)テンプレートのメタプログラミング。 どっちがいいの?私は最初の方法を試しましたが、この方法には多くの障害があることがわかります。特に、c ++ 11に関連するいくつかの制限があります。2番目のように見えるかもしれませんが、いくつかのトリックが必要です(c ++ 14から始まるgccおよびc ++ 11から始まるclangでサポートされている、演算子 ""を使用して文字列を分割して文字を分離する必要があります。 )。また、完全にTMPに基づくソリューションは、大きすぎて複雑すぎます。 以下は私の解決策です、私はそれについていくつかの提案を聞いてうれしいです。 http://coliru.stacked-crooked.com/a/0b8f1fae9d9b714b #include &lt;stdio.h&gt; template &lt;typename T&gt; struct Result { T value; bool valid; constexpr Result(T v) : value(v), valid(true) {} constexpr Result() : value(), valid(false) {} }; template &lt;typename T&gt; constexpr …
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.