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

C ++ 17は、2017年に承認されたC ++標準の名前です。これは、以前のC ++ 14標準に基づいて構築されており、コア言語と標準ライブラリを改善し、いくつかの新しい言語機能を追加しています。

1
C ++ 17での初期化後にインライン変数を変更できますか?
私のシナリオは以下です(それはclangでは機能しましたがgccでは機能しませんでした) liba.hpp: inline int MY_GLOBAL = 0; libother.cpp:(dll) #include "myliba.hpp" void myFunc() { // MYGLOBAL = 28; } someexe.cpp: RunAppThatUsesBothLibAandLibOther(); 問題は、インライン変数が実行時にすでに変更されていたため、28を期待した場所でインライン変数が0を示していたことです。MSVCはこれに同意しませんが、clangは私が期待することを行います。 問題は、私のシナリオでは、実行時にインライン変数を変更できるかどうかです。(変数をインライン展開することで問題を解決しました。)
11 c++  visual-c++  dll  clang  c++17 

6
無害な範囲ベースのforループが機能しない
以下はコンパイルされません: #include <iostream> int main() { int a{},b{},c{},d{}; for (auto& s : {a, b, c, d}) { s = 1; } std::cout << a << std::endl; return 0; } ゴッドボルトで試してみてください コンパイラエラーは次のとおりです。 error: assignment of read-only reference 's' 今私の実際の場合、リストはクラスのメンバー変数で構成されています。 これで、式がinitializer_list<int>実際にa、b、c、およびdをコピーするになるため、これは機能しません。したがって、変更もできません。 私の質問は2つあります。 このように範囲ベースのforループを記述できないようにする動機はありますか? 例えば。おそらく、裸のブレース式の特別なケースがあるかもしれません。 このタイプのループを修正する構文上のきちんとした方法は何ですか? この線に沿ったものが好ましいでしょう: for (auto& s : something(a, b, …

2
weak_ptrのリセットはshared_ptrに影響しますか?
私は使用にあまり慣れておらずweak_ptr、かなり混乱する状況に直面しています。Intel XE 2019 Composer update 5(パッケージ2019.5.281)をVisual Studio 2019 ver。と組み合わせて使用しています。16.2.5。64ビットでコンパイルします。標準のC ++ 17を使用しています。 これが私のスパイクソリューションのコードです。 #include <memory> #include <iostream> using namespace std; int main( int argc, char* argv[] ) { shared_ptr<int> sp = make_shared<int>( 42 ); cout << "*sp = " << *sp << endl; weak_ptr<int> wp = sp; cout << "*sp = …

3
std :: transformを並列実行ポリシーで使用できますか?
間違えなければ 、入出力イテレータと同じ範囲を使ってその場でstd::transform実行させることができます。私がいくつかのstd::vectorオブジェクトを持っていると仮定してvec、私は書くでしょう std::transform(vec.cbegin(),vec.cend(),vec.begin(),unary_op) 適切な単項演算を使用しますunary_op。 C ++ 17標準を使用しstd::execution::parて、最初の引数としてinを付けて、変換を並列実行したいと思います。これにより、関数がのcppreference記事のstd::transformオーバーロード(1)から(2)に変わります。ただし、このオーバーロードへのコメントは次のように述べています。 unary_op[...]終了反復子を含むすべての反復子を無効にしたり、関係する範囲の要素を変更したりしてはなりません。(C ++ 11以降) 「要素を変更する」とは、実際にアルゴリズムを使用できないことを意味しますか、それとも、誤って解釈した別の詳細について話しているのですか?

1
テンプレートテンプレートクラスでのGCC / C ++ 17の問題
次の2つのオーバーロードを検討してください template<typename T> bool test() { return true; } template<template<typename ...> class T> bool test() { return false; } 1つ目は通常のクラスで機能し、2つ目はインスタンス化されていないテンプレートで機能します。例えば: std::cout<<test<int>()<<std::endl; <-- this yields 1 std::cout<<test<std::list>()<<std::endl; <--this yields 0 ここで、次のテンプレート関数を考えます。 template<typename U> bool templfun(){ struct A{ bool f(){ return test<A>(); // <-- this gives an error } }; return test<A>(); …
10 c++  templates  gcc  clang  c++17 

2
関数型の引数のテンプレート引数の控除
次のプログラムを検討してください。 #include <iostream> template <typename T> void f( void ( *fn )( T ) ) { fn( 42 ); } void g( int x ) { std::cout << "g( " << x << " );\n"; } int main() { f( g ); } プログラムは正常にコンパイルされ、その出力は g( 42 ); 今度は、非テンプレート関数の名前を変更してみましょうgにf。 #include <iostream> …

5
バリアントのインデックスを取得して、そのコンテンツを取得するために使用できないのはなぜですか?
バリアントのコンテンツにアクセスしようとしています。何が入っているのかはわかりませんが、ありがたいことに、バリアントにはあります。だから私はバリアントにそれがどのインデックスにあるのか尋ねて、std::getそのコンテンツにそのインデックスを使うだけだと思った。 しかし、これはコンパイルされません: #include <variant> int main() { std::variant<int, float, char> var { 42.0F }; const std::size_t idx = var.index(); auto res = std::get<idx>(var); return 0; } エラーはstd::get呼び出しで発生します: error: no matching function for call to ‘get<idx>(std::variant<int, float, char>&)’ auto res = std::get<idx>(var); ^ In file included from /usr/include/c++/8/variant:37, from main.cpp:1: /usr/include/c++/8/utility:216:5: …
10 c++  c++17  variant 

2
読み取り専用のシナリオでnullで終了する文字列が必要になるのはいつですか?
私はstd::string_viewライブラリをいじくり回しており、私が取り組んでいるコードベースをstd::string_view可能な限り使用するように変更することを考えていました。ただし、私が読んだスレッドの多くでは、のstd::string_view代わりにいつ、どこで使用するかについて説明しましたconst std::string &。「nullで終了する文字列が必要ないとき」と多くの回答が言うのを見てきました。それで、私がWebを検索し始めたとき、「いつnullで終了する文字列が必要ですか?」この件に関して役立つ答えを見つけたことはありません。 にリンクする外部ライブラリの例が考えられますstd::string。そしてその場合、そのライブラリはそれを必要とするので、ヌルで終了する文字列が必要になります。別の例としては、文字列自体を変更する必要がある場合が考えられますが、変更する必要がある場合は渡されませんconst &。 では、nullで終了する文字列をいつ使用する必要があるでしょうか。 私が見たリンク: std :: string_viewはconst std :: string&よりどのくらい正確に高速ですか? std :: string_viewの代わりにconst&std :: stringを渡すのはいつですか? なぜ文字列ビューだけですか? C ++ 17でconst std :: string&引数を使用する意味はありますか?

2
チェーン時にコピーを回避する方法は?
以下の小さな例のように、連鎖タイプのクラスを作成しています。メンバー関数をチェーンすると、コピーコンストラクターが呼び出されるようです。コピーコンストラクタの呼び出しを取り除く方法はありますか?以下の私のおもちゃの例では、私が一時的なものだけを扱っていることは明らかであり、したがって、(標準ではないかもしれませんが、論理的には)省略があるはずです。省略をコピーするための2番目の最適な選択は、移動コンストラクターを呼び出すことですが、これは当てはまりません。 class test_class { private: int i = 5; public: test_class(int i) : i(i) {} test_class(const test_class& t) { i = t.i; std::cout << "Copy constructor"<< std::endl; } test_class(test_class&& t) { i = t.i; std::cout << "Move constructor"<< std::endl; } auto& increment(){ i++; return *this; } }; int main() { …
10 c++  c++14  c++17 


2
浮動小数点定数の疑似デストラクターを呼び出す有効な構文
次のデモプログラムを検討してください。 #include <iostream> int main() { typedef float T; 0.f.T::~T(); } このプログラムはによってコンパイルされMicrosoft Visual Studio Community 2019ます。 しかしclang、gccこのようなエラーを発行します prog.cc:7:5: error: unable to find numeric literal operator 'operator""f.T' 7 | 0.f.T::~T(); | ^~~~~ このような式を記述する場合、( 0.f ).T::~T()3つのコンパイラすべてがプログラムをコンパイルします。 したがって、疑問が生じ0.f.T::~T()ます。このレコードは構文的に有効ですか?そうでない場合、どの構文規則が違反していますか?

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 && y==0) print("msg"); …

1
演算子newとコンストラクターの引数の実行順序
DOES C ++は、順序指定SPEC operator newとのコンストラクタAでをnew C(A())。 g ++は順序をA()-> new-> C()にしますが、clang ++はそれをnew-> A()->にしC()ます。 違いは不特定の行動が原因ですか? g ++:7.4.0 clang ++:10.0.0 #include <iostream> #include <cstdlib> struct A { A() { std::cout << "call A()\n"; } }; struct C { C(A) { std::cout << "call S()\n"; } void *operator new(size_t s) { std::cout << "call …

1
ユーザー提供のstd :: allocator特殊化
::std名前空間内のクラステンプレートは、通常、ユーザー定義型のプログラムに特化できます。私はこのルールに例外を見つけませんでしたstd::allocator。 それで、std::allocator私は自分のタイプに特化することを許可されていますか?また、許可されている場合、std::allocatorの主なテンプレートのすべてのメンバーを提供する必要がありstd::allocator_traitsますか? このプログラムを検討してください #include<vector> #include<utility> #include<type_traits> #include<iostream> #include<limits> #include<stdexcept> struct A { }; namespace std { template<> struct allocator<A> { using value_type = A; using size_type = std::size_t; using difference_type = std::ptrdiff_t; using propagate_on_container_move_assignment = std::true_type; allocator() = default; template<class U> allocator(const allocator<U>&) noexcept {} value_type* allocate(std::size_t n) { if(std::numeric_limits<std::size_t>::max()/sizeof(value_type) …
8 c++  c++17  allocator 

1
#1664の提案された解決策を理解する方法
#1664の提案された解決策(提案された解決策1664)を見た後、私は関数テンプレートのデフォルト引数のルールに混乱しています、ここにコンテンツを引用してください: 8.1.5 [expr.prim.lambda]パラグラフ3によると クロージャタイプは、対応するラムダ式を含む最小のブロックスコープ、クラススコープ、または名前空間スコープで宣言されます。[注:これにより、クロージャタイプに関連付けられた名前空間とクラスのセットが決まります(6.4.2 [basic.lookup.argdep])。ラムダ宣言子のパラメータタイプは、これらの関連する名前空間とクラスには影響しません。—エンドノート] ただし、17.8.1 [temp.inst]パラグラフ13には、 デフォルトの引数を使用する必要がある方法で関数テンプレートfが呼び出された場合、依存名が検索され、セマンティクスの制約がチェックされ、デフォルトの引数で使用されているテンプレートのインスタンス化は、デフォルトの引数のように行われます。その時点で使用されている関数テンプレートfと同じスコープ、同じテンプレートパラメータ、同じアクセス権を持つ関数テンプレートの特殊化で使用される初期化子でした。 その場合、可能性は、テンプレート関数(または、おそらく、クラステンプレートのメンバー関数)のデフォルト引数のラムダ式のクロージャタイプが、の本体のブロックスコープで宣言されていると見なされることです。架空の機能テンプレートの特殊化。 次の例を考えてみましょう。 namespace J { inline namespace K { template <typename T> int zap(const T &t) { foo(t); return 0; } template <typename T> void zip(int = zap([] { })) { } } template <typename T> void foo(const T &) { } …

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