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

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

10
C ++での符号付きオーバーフローと未定義の動作(UB)
次のようなコードの使用について疑問に思っています int result = 0; int factor = 1; for (...) { result = ... factor *= 10; } return result; ループが何n度も繰り返される場合はfactor、10正確にn回数が掛けられます。ただし、合計回数をfactor掛けて使用します。ループの最後の反復以外はオーバーフローしないが、ループの最後の反復ではオーバーフローする可能性があると想定する場合、そのようなコードは受け入れ可能ですか?この場合、オーバーフローが発生した後、の値が使用されることはありません。10n-1factorfactor このようなコードが受け入れられるべきかどうかについて私は議論しています。ループがオーバーフローする可能性がある場合、乗算をifステートメント内に配置し、ループの最後の反復で乗算を実行しないことが可能です。欠点は、コードが煩雑になり、以前のすべてのループ反復をチェックする必要がある不要なブランチが追加されることです。また、ループの反復回数を1回減らし、ループの後にループ本体を1回複製することもできます。これもコードを複雑にします。 問題の実際のコードは、リアルタイムグラフィックスアプリケーションの総CPU時間の大部分を消費するタイトな内部ループで使用されます。

5
ラムダ自体内のC ++ラムダ関数のアドレスを取得するにはどうすればよいですか?
それ自体の中でラムダ関数のアドレスを取得する方法を理解しようとしています。これがサンプルコードです: []() { std::cout << "Address of this lambda function is => " << ???? }(); ラムダを変数にキャプチャしてアドレスを出力できることはわかっていますが、この無名関数が実行されているときにそれを実行したいと考えています。 これを行う簡単な方法はありますか?
53 c++  c++11  lambda  c++14  c++17 

3
等値演算子は、C ++ 20のカスタム宇宙船演算子の実装に対して定義されていません
<=>C ++ 20の新しい宇宙船オペレーターで奇妙な動作に遭遇しています。Visual Studio 2019コンパイラをで使用してい/std:c++latestます。 このコードは期待どおりに正常にコンパイルされます。 #include <compare> struct X { int Dummy = 0; auto operator<=>(const X&) const = default; // Default implementation }; int main() { X a, b; a == b; // OK! return 0; } ただし、Xを次のように変更すると、 struct X { int Dummy = 0; auto operator<=>(const X& …

3
1つの関数呼び出しC ++を使用して複数の定数クラスメンバーを初期化する
2つの異なる定数メンバー変数があり、どちらも同じ関数呼び出しに基づいて初期化する必要がある場合、関数を2回呼び出さずにこれを行う方法はありますか? たとえば、分子と分母が定数である分数クラス。 int gcd(int a, int b); // Greatest Common Divisor class Fraction { public: // Lets say we want to initialize to a reduced fraction Fraction(int a, int b) : numerator(a/gcd(a,b)), denominator(b/gcd(a,b)) { } private: const int numerator, denominator; }; これにより、GCD関数が2回呼び出されるため、時間が無駄になります。新しいクラスメンバーを定義し、gcd_a_b最初にgcdの出力を初期化リストのそれに割り当てることもできますが、これによりメモリが無駄になります。 一般に、関数呼び出しやメモリを無駄にせずにこれを行う方法はありますか?初期化リストに一時変数を作成できますか?ありがとうございました。

5
C ++のテンプレートフレンドリーな文字列から数値へ
C ++標準ライブラリには、文字列から数値型に変換する関数があります。 stoi stol stoll stoul stoull stof stod stold しかし、テンプレートコードでそれらを使用するのは面倒です。なぜ次のようなテンプレート関数がないのですか? template<typename T> T sto(...) 文字列を数値型に変換するには? それらを持たない技術的な理由は見当たらないが、何かが足りないのかもしれない。それらは、基礎となる名前付き関数を呼び出し、enable_if/ conceptsを使用して非数値型を無効にするように特殊化できます。 標準ライブラリに、文字列を数値型に変換するためのテンプレートに適した代替手段はありますか?

2
なぜ「システムを使用する」のか 悪い習慣とは考えていませんか?
私はC ++のバックグラウンドを持っており、この質問に対する回答を完全に理解して同意します。悪い習慣と考えていますか? だから、C#の経験があると、正反対のことがわかり using Some.Namespace;ます。文字通りどこでも使用されています。タイプの使用を開始するときはいつでも、そのネームスペースのusingディレクティブを最初に追加します(まだ存在しない場合)。.csで始まらなかった-file を見たことを思い出せませんusing System; using System.Collections.Generic; using X.Y.Z; etc...。実際、Visual Studioウィザードを使用して新しいファイルを追加すると、必要がない場合でも、いくつかのusingディレクティブが自動的に追加されます。したがって、C ++コミュニティでは基本的にリンチされますが、C#でもこれを行うことを推奨しています。少なくともこれは私にはそれが見える方法です。 現在、C#とC ++でディレクティブを使用することはまったく同じではないことを理解しています。また、using namespaceC ++でできる最も厄介なことの1つ、つまりヘッダーファイルに配置することの1つは、ヘッダーファイルとの概念がないため、C#で同等に厄介なものがないことを理解しています#include。 ただし、それらの違いにもかかわらず、C#とC ++でのディレクティブの使用は同じ目的に役立ちます。これはSomeType、ずっと長くするのではなく、常に入力するだけで済みますSome.Namespace.SomeType(C ++ ::ではの代わりに.)。これと同じ目的で、名前の衝突という危険も私には同じように見えます。 最良の場合、これによりコンパイルエラーが発生するため、修正する必要があるのは「のみ」です。最悪の場合でもコンパイルされ、コードは意図したものとは異なる動作をします。だから私の質問は:なぜ(どうやら)C#とC ++であまりにも悪いと考えられているディレクティブを使用しているのですか? 私が持っている答えのいくつかのアイデア(これらはどれも本当に私を満足させません): 名前空間は、C ++よりもC#の方がはるかに長く、ネストされる傾向があります(stdvs. System.Collection.Generic)。したがって、この方法でコードのノイズを除去することには、より多くの欲求と利益があります。しかし、これが真実であっても、この議論は標準の名前空間を調べたときにのみ適用されます。カスタムのものには、C#とC ++の両方で、任意の短い名前を付けることができます。 名前空間は、C ++よりもC#の方がはるかに「細かい」ように見えます。例として、C ++では標準ライブラリ全体std(およびのようないくつかの小さなネストされた名前空間chrono)が含まれますがSystem.IO、C#ではSystem.Threading、System.Textなどがあります。したがって、名前の衝突のリスクは小さくなります。しかし、これはただの直感です。私は実際にどのように多くの名前を使用すると、「インポート」カウントされませんでしたusing namespace stdとusing System。繰り返しになりますが、これが真実であっても、この議論は標準の名前空間を見たときにのみ適用されます。独自のものは、C#とC ++の両方で、必要に応じて細かく設計できます。 もっと議論はありますか?私は実際の難しい事実(もしあれば)に特に興味があり、意見にはあまり興味がありません。

2
A xor X = B + Xの解を見つけるアルゴリズム
整数AおよびBが与えられた場合、整数Xを見つけて次のようにします。 A、B <2 * 1e18 A xor X = B + X 数学を使ってこの方程式を解くことができるかどうか、私は強く疑います。これは私が3年前に遭遇したコーディングの問題であり、今でもこれを自分で解決することはできません。 これまでの私のコード:(これはブルートフォースソリューションです) #include <iostream> using namespace std; int main() { unsigned long long a, b; cin >> a >> b; for (unsigned long long x = 1; x < max(a, b); x++) { unsigned long long c = …
46 c++  xor 

3
std :: vector(ab)は自動ストレージを使用します
次のスニペットを考えてみましょう: #include <array> int main() { using huge_type = std::array<char, 20*1024*1024>; huge_type t; } 通常、デフォルトのスタックサイズは通常20MB未満であるため、ほとんどのプラットフォームでクラッシュします。 次のコードを考えてみましょう: #include <array> #include <vector> int main() { using huge_type = std::array<char, 20*1024*1024>; std::vector<huge_type> v(1); } 意外にもクラッシュします!トレースバック(最近のlibstdc ++バージョンの1つを使用)はinclude/bits/stl_uninitialized.hファイルにつながり、ここに次の行が表示されます。 typedef typename iterator_traits<_ForwardIterator>::value_type _ValueType; std::fill(__first, __last, _ValueType()); サイズ変更vectorコンストラクターは、要素をデフォルトで初期化する必要があります。これが実装方法です。明らかに、_ValueType()一時的にスタックがクラッシュします。 問題は、それが適合実装であるかどうかです。はいの場合、それは実際には巨大な型のベクトルの使用がかなり制限されていることを意味しますね?

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

2
多くの標準ライブラリタイプのC ++ 20でoperator!=が削除されるのはなぜですか?
cppreferenceによると、std::type_info::operator!=C ++ 20で削除されますが、std::type_info::operator==明らかに残っています。 背後にある理由は何ですか?不平等を比較することは無意味であることに同意するかもしれませんが、平等を比較することも同様に無意味ですよね? 同様に、operator!=などの容器を含む他の多くの標準ライブラリの種類のstd::unordered_map::operator!=とstd::unordered_set::operator!=cppreferenceに従って20 C ++で除去されます。 書き込みに持つことif(!(id1 == id2))に比べて任意のコードがどの明確にしないif(id1 != id2)だけで、反対、対照的に、...

5
集計初期化メンバーの脱落を防ぐことはできますか?
このような同じタイプの多くのメンバーを持つ構造体があります struct VariablePointers { VariablePtr active; VariablePtr wasactive; VariablePtr filename; }; 問題は、次のように構造体メンバーの1つ(例:)を初期化し忘れた場合ですwasactive。 VariablePointers{activePtr, filename} コンパイラはそれについて文句を言うことはありませんが、部分的に初期化されたオブジェクトが1つあります。この種のエラーを防ぐにはどうすればよいですか?コンストラクタを追加することはできますが、変数のリストを2回複製するため、これをすべて3回入力する必要があります。 C ++ 11の解決策がある場合は、C ++ 11の回答も追加してください(現在、そのバージョンに制限されています)。ただし、最近の言語標準も歓迎します。


7
2つのゼロ引数コンストラクターを区別する慣用的な方法
私はこのようなクラスを持っています: struct event_counts { uint64_t counts[MAX_COUNTERS]; event_counts() : counts{} {} // more stuff }; 通常私countsは示されているようにデフォルト(ゼロ)配列を初期化したいと思います。 ただし、プロファイリングによって特定された特定の場所では、配列が上書きされることがわかっているため、配列の初期化を抑制したいのですが、コンパイラーはそれを理解するのに十分なほどスマートではありません。 そのような「セカンダリ」ゼロ引数コンストラクタを作成する慣用的で効率的な方法は何ですか? 現在、次のuninit_tagように、ダミー引数として渡されるタグクラスを使用しています。 struct uninit_tag{}; struct event_counts { uint64_t counts[MAX_COUNTERS]; event_counts() : counts{} {} event_counts(uninit_tag) {} // more stuff }; 次に、構築event_counts c(uninit_tag{});を抑制したいときのように、no-initコンストラクターを呼び出します。 私は、ダミークラスの作成を含まない、または何らかの方法でより効率的なソリューションなどを受け入れています。

2
C ++でSFINAEを機能させる方法
プロジェクトで関数SFINAEを頻繁に使用しており、次の2つのアプローチ(スタイル以外)に違いがあるかどうかはわかりません。 #include <cstdlib> #include <type_traits> #include <iostream> template <class T, class = std::enable_if_t<std::is_same_v<T, int>>> void foo() { std::cout << "method 1" << std::endl; } template <class T, std::enable_if_t<std::is_same_v<T, double>>* = 0> void foo() { std::cout << "method 2" << std::endl; } int main() { foo<int>(); foo<double>(); std::cout << "Done..."; std::getchar(); …
40 c++  sfinae 

2
スイッチがチェーン化されているのと同じように最適化されていないのはなぜですか?
次のsquareの実装は、連鎖ifステートメントに期待するような一連のcmp / jeステートメントを生成します。 int square(int num) { if (num == 0){ return 0; } else if (num == 1){ return 1; } else if (num == 2){ return 4; } else if (num == 3){ return 9; } else if (num == 4){ return 16; } else if (num == …

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