タグ付けされた質問 「c++」

C ++は汎用プログラミング言語です。もともとCの拡張として設計され、構文は似ていますが、現在は完全に異なる言語になっています。このタグは、C ++コンパイラでコンパイルされる(される)コードに関する質問に使用します。特定の標準リビジョン[C ++ 11]、[C ++ 14]、[C ++ 17]または[C ++ 20]などに関連する質問には、バージョン固有のタグを使用します。

3
int(0)からベクター内のポインターへの暗黙的な変換を回避する方法
JSONでキーへのパスのすべてのノード名を収集したい状況があります。配列インデックス「0」、「1」の条件も許可されていることを考慮してください。ただし、引用符を忘れがちであり、逆参照するとクラッシュする可能性があります。これを拒否したいのですが。例: #include <vector> #include <iostream> int func(const std::vector<const char*>& pin) { return pin.size(); } int main() { // {"aname", "3", "path", "0"} wanted but this still compile std::cout << func({"aname", "3", "path", 0}) << std::endl; } 私はこれを見つけて試してみました非構築関数の暗黙的な変換をどのように回避しますか?次のように: #include <vector> #include <iostream> int func(const std::vector<const char*>& pin) { return pin.size(); } …

2
nullポインタ引数と不可能な事後条件を使用して標準例外を構築します
次のプログラムを検討してください。 #include<stdexcept> #include<iostream> int main() { try { throw std::range_error(nullptr); } catch(const std::range_error&) { std::cout << "Caught!\n"; } } libstdc ++を使用したGCCおよびClang std::terminateは、メッセージを表示してプログラムを呼び出し、中止します terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_S_construct null not valid 例外の構築時にlibc ++のClangがsegfaultします。 godboltを参照してください。 コンパイラは標準に準拠していますか?標準の関連セクション[diagnostics.range.error](C ++ 17 N4659)は言っていstd::range_error有するconst char*好まれるべきであるコンストラクタのオーバーロードconst std::string&オーバーロード。このセクションでは、コンストラクターの前提条件についても述べておらず、事後条件についてのみ述べています。 事後条件:strcmp(what(), what_­arg) == 0。 what_argnullポインターの場合、この事後条件は常に未定義の動作を持っています。つまり、これは私のプログラムにも未定義の動作があり、両方のコンパイラーが準拠して動作することを意味しますか?そうでない場合、標準でそのような不可能な事後条件をどのように読むべきですか? 考え直してみれば、それは私のプログラムにとって未定義の動作を意味しているに違いないと思います。そうしないと、(有効な)ヌル終了文字列を指さないポインタも許可されるため、明らかに意味がありません。 …

2
一時的にパイプされた範囲操作に戻すことはできますか?
generate_my_rangea range(特にis regular)をモデル化するクラスがあるとします。次のコードは正しいですか: auto generate_my_range(int some_param) { auto my_transform_op = [](const auto& x){ return do_sth(x); }; return my_custom_rng_gen(some_param) | ranges::views::transform(my_transform_op); } auto cells = generate_my_range(10) | ranges::to<std::vector>; my_custom_rng_gen(some_param)(最初の)パイプ演算子によって値が取得されますか、またはgenerate_my_rangeスコープを離れると、ダングリング参照がありますか? 関数呼び出しと同じranges::views::transform(my_custom_rng_gen(some_param),my_transform_op)でしょうか? 左辺値参照を使用した場合、それは正しいでしょうか?例えば: auto generate_my_range(int some_param) { auto my_transform_op = [](const auto& x){ return do_sth(x); }; auto tmp_ref = my_custom_rng_gen(some_param); return tmp_ref | …
9 c++  range-v3 

1
インスタンスを作成せずにstd :: array <T、N>の要素数を取得する方法は?
はありますがstd::array&lt;T, N&gt;::size()、静的ではないため、のインスタンスが必要ですstd::array。配列のインスタンスを作成せずに、それが返す値(Nのstd::array&lt;T, N&gt;)を取得する方法はありますか?通常の配列では、を使用することもできましたがsizeof、sizeof(std::array&lt;T, N&gt;) == N * sizeof(T)本当であるという保証はありません。
9 c++  arrays  c++11  sizeof 

2
どのような名前空間があり、どのような規則がありますか?
注:この質問は、name spaceではなくについてnamespaceです。 C ++標準にはへの参照がいくつかありますがname space、これの定義はわかりません。標準では、ラベルとマクロは異なる名前空間にあると規定されています。への他のすべての参照name spaceは、このようにC / C ++互換性セクションにあります(現在のドラフト): これは、CとC ++の間のいくつかの非互換性の1つであり、新しいC ++名前空間定義に起因する可能性があります。この場合、名前を単一のスコープ内でタイプおよび非タイプとして宣言して、非タイプ名で非表示にすることができます。タイプ名。キーワードclass、struct、unionまたはenumを使用してタイプ名を参照する必要があります。この新しい名前空間の定義は、C ++プログラマーに重要な表記上の便宜を提供し、ユーザー定義型の使用を基本型の使用に可能な限り類似させるのに役立ちます。 この新しい名前空間の定義は何ですか?規格のどこにありますか?正確なルールは何ですか?ルールは「非タイプはタイプを非表示にする」よりも複雑なようです。同様に、これはコンパイルされません: typedef int Foo; // Foo is a type void Foo(); // not a type, but compile error, instead of hiding しかし、これは: struct Foo { }; // Foo is a type as well void Foo(); // This …
9 c++  namespaces 

1
存続期間が終了したオブジェクトのメンバー関数コルーチンを再開するのはUBですか?
この質問は、このコメントから生じています:C ++ 20コルーチンのラムダ寿命の説明 この例について: auto foo() -&gt; folly::coro::Task&lt;int&gt; { auto task = []() -&gt; folly::coro::Task&lt;int&gt; { co_return 1; }(); return task; } したがって、問題は、によって返されたコルーチンを実行するfooとUBになるかどうかです。 (オブジェクトのライフタイムが終了した後の)メンバー関数の「呼び出し」はUBです。http://eel.is/c++draft/basic.life#6.2 ...オブジェクトが配置される、または配置された保管場所のアドレスを表すポインターは、限られた方法でのみ使用できます。[...]次の場合、プログラムは未定義の動作をします。 [...] -ポインタは非静的データメンバにアクセスしたりするために使用されるオブジェクトの非静的メンバ関数を呼び出し、または ただし、この例では: ()ラムダの有効期間中にラムダの演算子が呼び出されます その後、中断され、 次にラムダが破壊され、 その後、メンバー関数(演算子())はある時点で再開されます。 この再開は未定義の動作と見なされますか?

1
不特定の暗黙的なオブジェクトの作成
以来P0593低レベルのオブジェクトの操作のためのオブジェクトの暗黙の作成は、オブジェクトが現在作成され、承認された暗黙的に C ++ 20で。 具体的に提案により導入された文言は、(のような特定の操作が可能にstd::malloc)自動的に特定の種類のオブジェクトの寿命を作成して開始するには、いわゆる暗黙の一生のタイプ、場合このようなオブジェクトの導入は持っているそれ以外の場合は未定義の動作でプログラムを引き起こします定義された動作。[intro.object] / 10を参照してください。 ドラフトはさらに、プログラムで定義された動作を与えるために暗黙的に作成できるそのようなオブジェクトの複数のセットがある場合、これらのセットのどれが作成されるかは不特定であると述べています。(関連する文は、私がアクセスできた最後の提案リビジョンR5には存在しないようですが、ドラフトコミットにあります。) 暗黙的に作成されたオブジェクトセットのこの選択が観察可能なプログラムは実際にありますか?言い換えると、この新しいルールを通じて、定義されているが特定されていない動作を伴うプログラムがあり、(複数の可能なオブジェクトのうち)作成された暗黙オブジェクトのタイプのセットを出力から推測できるようになっていますか? または、この文は、抽象的なマシンでのプログラムの実行を(観察可能な影響なしに)明確にすることだけを目的としていましたか?

2
C ++がFoo <T> :: Foo(T &&)の呼び出しでTを推定できないのはなぜですか?
次のテンプレート構造があるとします。 template&lt;typename T&gt; struct Foo { Foo(T&amp;&amp;) {} }; これはコンパイルTされ、次のように推定されますint。 auto f = Foo(2); しかし、これはコンパイルされません:https : //godbolt.org/z/hAA9TE int x = 2; auto f = Foo(x); /* &lt;source&gt;:12:15: error: no viable constructor or deduction guide for deduction of template arguments of 'Foo' auto f = Foo(x); ^ &lt;source&gt;:7:5: note: candidate function …

2
Cのconst修飾子とC ++のconst修飾子の違いは何ですか?
I'veが見つかりました。コメント、ユーザのRを...: CとC ++は同じ言語ではありません。特に、C constはC ++とは何の関係もありませんconst。 constCのconst修飾子とC ++ の修飾子の違いの1つは、そのデフォルトのリンケージです。 constC ++では、修飾子を使用して名前空間スコープで宣言されたオブジェクトは内部リンケージを持ちますが、Cではconst、グローバルスコープで宣言された修飾子を持つオブジェクト(static前に修飾子を持たないconst)は外部リンケージを持ちます。 しかし、CとC ++の言語間で他にどのように異なるのですか?両方の言語で、どちらも同じ種類の概念と目的を持っていると思いました。 私の質問: Cのconst修飾子とC ++のconst修飾子の違いは何ですか? 回答「ポーラ」はどのようにCとC ++で異なりますか?正確な差異指していない間の文脈におけるCおよびC ++の言語const修飾子を。特定の言語で実行できない、または実行できることのみ。

2
スレッドセーフルールによって提案された非const引数を使用してコンストラクターをコピーしますか?
レガシーコードの一部のラッパーがあります。 class A{ L* impl_; // the legacy object has to be in the heap, could be also unique_ptr A(A const&amp;) = delete; L* duplicate(){L* ret; legacy_duplicate(impl_, &amp;L); return ret;} ... // proper resource management here }; このレガシーコードでは、オブジェクトを「複製」する関数はスレッドセーフではない(同じ最初の引数を呼び出す場合)ためconst、ラッパーでマークされていません。私は現代のルールに従っていると思います:https : //herbsutter.com/2013/01/01/video-you-dont-know-const-and-mutable/ これduplicateは、そうではない詳細を除いて、コピーコンストラクタを実装する良い方法のように見えconstます。したがって、これを直接行うことはできません。 class A{ L* impl_; // the legacy object has …

2
C ++-ここで「テンプレート」キーワードが必要なのはなぜですか?
私は次のコードを持っています: template &lt;typename TC&gt; class C { struct S { template &lt;typename TS&gt; void fun() const {} }; void f(const S&amp; s) { s.fun&lt;int&gt;(); } }; // Dummy main function int main() { return 0; } これをgcc 9.2とclang(9.0)の両方でビルドすると、templateを呼び出すために必要なキーワードが原因で、コンパイルエラーが発生しますfun。Clangのショー: error: use 'template' keyword to treat 'fun' as a dependent template name …

2
プログラマーレベルのC ++ std :: atomicでは何が保証されますか?
私はに関するいくつかの記事、講演、stackoverflowの質問を聞いて読みましstd::atomicたが、私はそれをよく理解していることを確認したいと思います。MESI(または派生した)キャッシュコヒーレンシプロトコル、ストアバッファー、キューの無効化などで遅延が発生する可能性があるため、キャッシュライン書き込みの可視性とまだ少し混乱しています。 私はx86がより強力なメモリモデルを持っていることを読みました。キャッシュの無効化が遅れると、x86は開始された操作を元に戻すことができます。しかし、私は今、プラットフォームに関係なく、C ++プログラマーとして何を想定すべきかについてのみ興味があります。 [T1:スレッド1 T2:スレッド2 V1:共有アトミック変数] std :: atomicは、 (1)変数でデータ競合は発生しません(キャッシュラインへの排他的アクセスのおかげ)。 (2)使用するmemory_orderに応じて、(バリアを使用して)順次整合性が発生することが保証されます(バリアの前、バリアの後、またはその両方)。 (3)T1のアトミック書き込み(V1)の後、T2のアトミックRMW(V1)はコヒーレントになります(そのキャッシュラインはT1に書き込まれた値で更新されます)。 しかし、キャッシュコヒーレンシープライマーの言及として、 これらすべての意味は、デフォルトで、ロードが古いデータをフェッチできることです(対応する無効化リクエストが無効化キューに置かれていた場合)。 それで、次は正しいですか? (4)std::atomicT2がT1のアトミックwrite(V)の後にアトミックread(V)の「古い」値を読み取らないことを保証しません。 (4)が正しいかどうかの質問:T1のアトミック書き込みが遅延に関係なくキャッシュラインを無効にする場合、アトミックRMW操作がアトミック読み取りではなく無効化が有効になるのをT2が待機しているのはなぜですか? (4)が間違っている場合の質問:スレッドは実行時に「古くなった」値を読み、「それが見える」のはいつですか? 回答ありがとうございます アップデート1 だから私はそのとき(3)について間違っていたようです。次のインターリーブを想像してください。最初のV1 = 0の場合: T1: W(1) T2: R(0) M(++) W(1) この場合、T2のRMWはW(1)の後に完全に発生することが保証されていますが、それでも「古い」値を読み取ることができます(私は間違っていました)。これによると、atomicは完全なキャッシュコヒーレンシを保証せず、順次一貫性のみを保証します。 アップデート2 (5)この例を想像してみてください(x = y = 0でアトミックです): T1: x = 1; T2: y = 1; T3: if (x==1 &amp;&amp; y==0) print("msg"); …

1
GCCが不正なconstexprラムダ呼び出しを報告できない
以下は、IIFE(Immediately Called Lambda-Axpression)として表される未定義の動作の2つのテストケースです。 constexpr auto test3 = []{ int* p{}; { int x{}; p = &amp;x; } return *p; // Undefined Behaviour }(); // IIFE constexpr auto test4 = []{ int x = std::numeric_limits&lt;int&gt;::min(); int y = -x; // Undefined Behaviour return y; }(); int main() {} GCCトランクでコンパイルすると、test4で未定義の動作を示すため、正しく拒否されconstexprます。一方、test3受け入れられます。 GCCは受け入れる権利がありますtest3か?

1
異なるコンパイラーでのvoid **への変換
次のコードをさまざまなコンパイラで実行しています。 int main() { float **a; void **b; b = a; } 私が収集できたことから、汎用ポインタでvoid **はありません。これは、別のポインタからの変換がコンパイルされたり、少なくとも警告をスローしたりしないことを意味します。しかし、ここに私の結果があります(すべてWindowsで行われます): gcc-期待どおりに警告をスローします。 g ++ -予想どおりエラーをスローします(これは、C ++の型の許容度が低いためです)。 MSVC(cl.exe) -/ Wallが指定されていても、警告は一切表示されません。 私の質問は、全体について何か不足しているのですか?MSVCが警告を生成しない特定の理由はありますか?MSVC は、から void **への変換時に警告を生成しfloat **ます。 もう1つの注意点:a = b明示的な変換に置き換えた場合a = (void **)b、どのコンパイラも警告をスローしません。これは無効なキャストだと思ったので、なぜ警告がないのでしょうか? 私がこの質問をしているのは、CUDAと公式のプログラミングガイド(https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory)を学び始めていたからです。次のコードが見つかります: // Allocate vectors in device memory float* d_A; cudaMalloc(&amp;d_A, size); の最初の引数は型であるvoid **ため&amp;d_A、これはfor への暗黙の変換を実行する必要cudaMallocがありvoid **ます。同様のコードがドキュメント全体にあります。これはNVIDIAの終わりのずさんな作業ですか、それとも私は何か不足していますか?nvccはMSVCを使用しているため、コードは警告なしでコンパイルされます。
9 c++  c  cuda 

1
関数ポインターの配列から関数ポインターをテンプレート引数として渡す
関数ポインターの配列から関数ポインターをテンプレート引数として渡したいのですが。Intellisenseが何かがおかしいと文句を言うのに、私のコードはMSVCを使用してコンパイルしているようです。gccとclangはどちらもコードのコンパイルに失敗します。 次の例を考えてみます。 static void test() {} using FunctionPointer = void(*)(); static constexpr FunctionPointer functions[] = { test }; template &lt;FunctionPointer function&gt; static void wrapper_function() { function(); } int main() { test(); // OK functions[0](); // OK wrapper_function&lt;test&gt;(); // OK wrapper_function&lt;functions[0]&gt;(); // Error? } MSVCはコードをコンパイルしますが、Intellisenseは次のエラーを出します:invalid nontype template argument of type "const …
9 c++  templates  c++14 

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.