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

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

3
非constへのポインターと同じアドレスのconst引数へのポインターを使用した関数呼び出し
データの配列を入力し、ポインターを使用して別のデータの配列を出力する関数を書きたいのですが。 コンパイラがconstを最適化できることを知っているので、両方が同じアドレスsrcをdst指している場合、結果はどうなのかと思います。未定義の動作ですか?(CとC ++の両方にタグを付けました。これは、答えが異なるかどうかわからないためです。両方について知りたいのです。) void f(const char *src, char *dst) { dst[2] = src[0]; dst[1] = src[1]; dst[0] = src[2]; } int main() { char s[] = "123"; f(s,s); printf("%s\n", s); return 0; } 上記の質問に加えてconst、元のコードでを削除すると、これは明確になりますか?

3
2つの範囲内でベクトルを降順に並べ替える
整数のベクトルがあるとしましょう: std::vector<int> indices; for (int i=0; i<15; i++) indices.push_back(i); 次に、降順に並べ替えます。 sort(indices.begin(), indices.end(), [](int first, int second) -> bool{return indices[first] > indices[second];}) for (int i=0; i<15; i++) printf("%i\n", indices[i]); これにより、以下が生成されます。 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 ここで、数字3、4、5、6を最後に移動し、それらの降順を維持したいとします(できればsort2回目に使用する必要はありません)。つまり、ここに私が欲しいものがあります: 14 13 12 11 10 …

1
Clangはコードをコンパイルしませんが、gccとmsvcはそれをコンパイルしました
何が問題なのか理解できません。コードまたはコンパイラ(可能性が低い)のどちらかです。次のようなコードがあります。 #include <iostream> #include <type_traits> #include <set> template<typename T, typename = void> struct TestA: std::false_type {}; template<typename T> struct TestA<T, std::void_t<typename T::reverse_iterator>> : std::true_type {}; template<typename T> struct TestA<T, std::void_t<typename T::dummy_iterator>> : std::true_type {}; int main() { std::cout << TestA<std::set<int>>::value; } GCCとMSVCの両方でコンパイルします。GCCとMSVC 17(ローカル)および19の異なるバージョンを使用して、godboltでテストしました。リンクは次のとおりです:https ://godbolt.org/z/Enfm6L 。 しかし、Clangはそれをコンパイルせず、エラーを出します。 redefinition of `'TestA<T, std::void_t<typename …

2
キーとしてのベクトルは、C ++で内部的にどのように機能しますか?
このSOの答えは、キーのベクトルを持つSTLマップ、ベクトルをキーとして使用できることを示しています。したがって、ベクターをキーとして使用する場合。キーは一意である必要があるため、実際にはどのように機能mapしますか?同じ要素を持つ別のベクターを挿入すると、要素ごとに重複した要素がないかチェックされますか、ベクターの名前が何かを指定していますか?配列の名前と同様に、ベースアドレスを表します。したがって、この場合はベースアドレスをキーとして使用できるため、配列をキーとして使用できますが、ベクトルの場合はキーは何ですか。内部ではどのように機能しますか。 ベクトルの名前を出力するとエラーになるので vector<int> v; cout<<v; //error
14 c++  arrays  dictionary  vector  stl 

1
GCCがstd :: vector :: sizeがこのループで変更されないと想定できないのはなぜですか?
if (i < input.size() - 1) print(0);このループで最適化されinput.size()、すべての反復で読み取られるわけではない同僚に私は主張しましたが、これはそうではありません! void print(int x) { std::cout << x << std::endl; } void print_list(const std::vector<int>& input) { int i = 0; for (size_t i = 0; i < input.size(); i++) { print(input[i]); if (i < input.size() - 1) print(0); } } gccオプション付きのコンパイラエクスプローラによると、-O3 -fno-exceptions実際にはinput.size()各反復を読み取りlea、減算を実行するために使用しています。 movq 0(%rbp), …
14 c++  gcc  assembly 

1
要素を完全に転送してstd :: vectorをリスト初期化できますか?
std :: vectorの集約 リストの初期化は、移動がより適切な場合にコピーの初期化を実行することに気付きました。同時に、複数のemplace_backsが必要な処理を実行します。 テンプレート関数を書くというこの不完全な解決策しか思いつかなかったinit_emplace_vector。ただし、明示的ではない単一値コンストラクターにのみ最適です。 template <typename T, typename... Args> std::vector<T> init_emplace_vector(Args&&... args) { std::vector<T> vec; vec.reserve(sizeof...(Args)); // by suggestion from user: eerorika (vec.emplace_back(std::forward<Args>(args)), ...); // C++17 return vec; } 質問 std :: vectorをできるだけ効率的に初期化するために、本当にemplace_backを使用する必要がありますか? // an integer passed to large is actually the size of the resource std::vector<large> v_init { …

1
スタックメモリが使用されていないときに割り当てられるのはなぜですか?
次の例を考えてみます。 struct vector { int size() const; bool empty() const; }; bool vector::empty() const { return size() == 0; } 生成されたアセンブリコードvector::empty(clangによる最適化あり): push rax call vector::size() const test eax, eax sete al pop rcx ret なぜスタックスペースを割り当てるのですか?一切使用しておりません。省略することができます。MSVCとgccの最適化ビルドもこの関数にスタックスペースを使用するため(godboltを参照)、理由があるはずです。pushpop

1
空の基本クラスもメンバー変数であるときに、空の基本最適化が禁止されているのはなぜですか?
空のベース最適化は素晴らしいです。ただし、次の制限があります。 同じ基本型の2つの基本サブオブジェクトはオブジェクト表現内で異なるアドレスを持つ必要があるため、空の基本クラスの1つが最初の非静的データメンバーの型の型または基本でもある場合、空の基本最適化は禁止されています。最も派生したタイプの。 この制限を説明するには、次のコードを検討してください。static_assert失敗します。一方、どちらFooかBarを変更するか、代わりにから継承するBase2と、エラーが回避されます。 #include <cstddef> struct Base {}; struct Base2 {}; struct Foo : Base {}; struct Bar : Base { Foo foo; }; static_assert(offsetof(Bar,foo)==0,"Error!"); 私はこの振る舞いを完全に理解しています。私が理解していないのは、この特定の動作が存在する理由です。見落としではなく明示的な追加であるため、明らかに理由で追加されました。これの根拠は何ですか? 特に、2つの基本サブオブジェクトが異なるアドレスを持つ必要があるのはなぜですか?上記のBarはタイプでfooあり、そのタイプのメンバー変数です。Barの基本クラスがのタイプの基本クラスと関係がある理由foo、またはその逆の理由がわかりません。 実際、私はどちらかと言えば、それを含むインスタンス&fooのアドレスと同じであることを期待しBarます。他の状況で必要になるためです(1)。結局のところ、私はvirtual継承についてBase2特別なことは何もしていません。基本クラスは関係なく空であり、を使用したコンパイルは、この特定のケースでは何も壊れないことを示しています。 しかし、明らかにこの推論はどういうわけか間違っており、この制限が必要になる他の状況があります。 答えがC ++ 11以降であるとしましょう(私は現在C ++ 17を使用しています)。 (1)注:EBOはC ++ 11でアップグレードされ、特にに対して必須になりましたStandardLayoutType(ただしBar、上記でははではありませんStandardLayoutType)。

1
__func__ポインターの2つのconstexprインスタンスの違いはまだconstexprですか?
これは有効なC ++ですか? int main() { constexpr auto sz = __func__ - __func__; return sz; } GCCとMSVCは大丈夫だと思っていますが、Clangはそうではないと思っています:Compiler Explorer。 すべてのコンパイラは、これが問題ないことに同意しています:コンパイラエクスプローラー。 int main() { constexpr auto p = __func__; constexpr auto p2 = p; constexpr auto sz = p2 - p; return sz; } Clangはこれも好きではありませんが、他のものは問題ありません:Compiler Explorer int main() { constexpr auto p = …


1
これはstd :: gcdのバグですか?
私はstd::gcd予期しないことに気付いたこの振る舞いに遭遇しました: #include <iostream> #include <numeric> int main() { int a = -120; unsigned b = 10; //both a and b are representable in type C using C = std::common_type<decltype(a), decltype(b)>::type; C ca = std::abs(a); C cb = b; std::cout << a << ' ' << ca << '\n'; std::cout << …

1
if constexpr-破棄されたステートメントが完全にチェックされるのはなぜですか?
私はGCC 10でc ++ 20 constevalをいじくり回して、このコードを書きました #include <optional> #include <tuple> #include <iostream> template <std::size_t N, typename Predicate, typename Tuple> consteval std::optional<std::size_t> find_if_impl(Predicate&& pred, Tuple&& t) noexcept { constexpr std::size_t I = std::tuple_size_v<std::decay_t<decltype(t)>> - N; if constexpr (N == 0u) { return std::nullopt; } else { return pred(std::get<I>(t)) ? std::make_optional(I) : find_if_impl<N …

2
単純なデフォルトコンストラクターがアクションを実行しない場合、mallocを使用して単純な構成可能なオブジェクトを作成できないのはなぜですか?
単純なデフォルトコンストラクターについて、cppreferenceから引用された次の段落を理解するのが困難です。私はstackoverflowを検索しましたが、それでも明確な答えが得られませんでした。助けてください。 単純なデフォルトコンストラクターは、アクションを実行しないコンストラクターです。C言語と互換性のあるすべてのデータ型(POD型)は、簡単にデフォルトで構築できます。ただし、Cとは異なり、単純なデフォルトコンストラクターを持つオブジェクトは、std :: mallocで割り当てられたメモリなど、適切に配置されたストレージを単に再解釈することによって作成することはできません。 具体的には、自明なデフォルトコンストラクターが何もしない場合、ストレージを再解釈して、指定されたタイプのオブジェクトがあるふりをすることができないのはなぜですか?これにより発生する可能性のある未定義の動作の例をいくつか教えていただけますか?

5
パラメーターパックのグループ化またはペア化された折り畳みを作成する方法は?
template<class Msg, class... Args> std::wstring descf(Msg, Args&&... args) { std::wostringstream woss; owss << Msg << ". " << ... << " " << args << ": '" << args << "' ";//not legal at all //or owss << Msg << ". " << args[0] << ": '" << args[1] << …

2
コピーと移動のコンストラクターは自動友達ですか?
コピーまたは移動コンストラクターを定義すると、別のクラスのプライベート変数にアクセスできます。C ++はそれらfriendを自動的に相互に作成しますか? 例えば: my_str::my_str(my_str&& m) { size_ = m.size_; //accessing private variable another my_str class buff_ = m.buff_; //accessing private variable another my_str class m.buff_ = nullptr; m.size_ = 0; }
14 c++  friend-class 

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