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

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

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 << …

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
GCC9はstd :: variantの値のない状態を回避できますか?
私は最近、std::visitコンパイラ間の最適化の素晴らしい比較につながるRedditディスカッションをフォローしました。私は次のことに気づきました:https : //godbolt.org/z/D2Q5ED GCC9とClang9の両方(同じstdlibを共有していると思います)は、すべての型がいくつかの条件を満たす場合に、値のない例外をチェックしてスローするためのコードを生成しません。これはより優れたcodegenにつながるため、MSVC STLで問題を提起し、次のコードが提示されました。 template <class T> struct valueless_hack { struct tag {}; operator T() const { throw tag{}; } }; template<class First, class... Rest> void make_valueless(std::variant<First, Rest...>& v) { try { v.emplace<0>(valueless_hack<First>()); } catch(typename valueless_hack<First>::tag const&) {} } 主張によると、これによりすべてのバリアントが無価値になり、ドキュメントを読むと次のようになります。 まず、現在含まれている値(存在する場合)を破棄します。次にT_I、引数を使用してtypeの値を作成する場合と同様に、含まれている値を直接初期化します。std::forward<Args>(args)....例外がスローされた場合、*thisvalueless_by_exceptionになることがあります。 わからないこと:なぜ「かもしれない」と記載されているのですか?操作全体がスローされた場合、古い状態を維持することは合法ですか?これはGCCが行うことなので、 // For suitably-small, trivially copyable types we …

1
std :: swapがClang / Winのvector <bool>要素で機能しないのはなぜですか?
私はこのようなコードを持っています: #include &lt;vector&gt; #include &lt;utility&gt; int main() { std::vector&lt;bool&gt; vb{true, false}; std::swap(vb[0], vb[1]); } vector&lt;bool&gt;脇見の健全性についての議論は、これはうまく機能していました: Mac用のClang Visual Studio for Windows Linux用GCC 次に、WindowsでClangを使用してビルドしようとすると、次のエラー(要約)が表示されました。 error: no matching function for call to 'swap' std::swap(vb[0], vb[1]); ^~~~~~~~~ note: candidate function [with _Ty = std::_Vb_reference&lt;std::_Wrap_alloc&lt;std::allocator&lt;unsigned int&gt; &gt; &gt;, $1 = void] not viable: expects an …

1
std :: vector範囲コンストラクターは明示的な変換を呼び出すことができますか?
次のプログラムは整形式ですか? #include &lt;vector&gt; struct A { explicit A(int) {} }; int main() { std::vector&lt;int&gt; vi = {1, 2, 3, 4, 5}; std::vector&lt;A&gt; va(vi.begin(), vi.end()); } C ++ 17 [sequence.reqmts]によると、 X u(i, j); どこXシーケンスコンテナは、されています。 TでなければならEmplaceConstructibleにXから*i。 ただし、前の段落では、次のように述べられています。 iそして、j表すイテレータは入力イテレータの要件を満たすとに暗黙的に変換要素を指しvalue_type、 したがって、両方の要件が満たされる必要があるように思えます:範囲の値の型は、コンテナーの値の型に暗黙的に変換可能で EmplaceConstructibleなければならず、満たす必要があります(つまり、アロケーターは必要な初期化を実行できる必要があります) 。以来intに暗黙的に変換できませんA、このプログラムは、病気に形成されなければなりません。 ただし、驚くべきことに、GCCでコンパイルされているようです。
14 c++  c++17 

3
ラムダ関数をオーバーロードする
単純なローカルラムダ関数をオーバーロードする方法は? 元の問題のSSE: #include &lt;iostream&gt; #include &lt;map&gt; void read() { static std::string line; std::getline(std::cin, line); auto translate = [](int idx) { constexpr static int table[8]{ 7,6,5,4,3,2,1,0 }; return table[idx]; }; auto translate = [](char c) { std::map&lt;char, int&gt; table{ {'a', 0}, {'b', 1}, {'c', 2}, {'d', 3}, {'e', 4}, {'f', 5}, …

1
C ++ nullptr実装はどのように機能しますか?
仕組みを知りたいnullptrです。規格N4659およびN4849は次のように述べています。 タイプが必要std::nullptr_tです。 そのアドレスを取ることはできません。 これは、ポインターおよびメンバーへのポインターに直接変換できます。 sizeof(std::nullptr_t) == sizeof(void*); への変換boolはfalseです。 その値は、と同じように整数型に変換できます(void*)0が、逆方向には変換できません。 したがって、基本的にはと同じ意味を持つ定数ですが、(void*)0型が異なります。std::nullptr_t私のデバイスでの実装を見つけました。それは次のとおりです。 #ifdef _LIBCPP_HAS_NO_NULLPTR _LIBCPP_BEGIN_NAMESPACE_STD struct _LIBCPP_TEMPLATE_VIS nullptr_t { void* __lx; struct __nat {int __for_bool_;}; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {} _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;} template &lt;class _Tp&gt; _LIBCPP_INLINE_VISIBILITY _LIBCPP_CONSTEXPR operator …

2
ラムダでstatic_assertを指定したconstexprの場合、どのコンパイラが正しいですか?
static_assertでa if constexprを使用する場合は、条件をいくつかのテンプレートパラメータに依存させる必要があります。興味深いことに、コードがラムダでラップされている場合、gccとclangは一致しません。 次のコードはgccでコンパイルされますが、clang if constexprがtrueでなくても、clangはアサートをトリガーします。 #include &lt;utility&gt; template&lt;typename T&gt; constexpr std::false_type False; template&lt;typename T&gt; void foo() { auto f = [](auto x) { constexpr int val = decltype(x)::value; if constexpr(val &lt; 0) { static_assert(False&lt;T&gt;, "AAA"); } }; f(std::integral_constant&lt;int, 1&gt;{}); } int main() { foo&lt;int&gt;(); } ここでライブ例。 それは簡単に置き換えることによって固定することが可能False&lt;T&gt;でFalse&lt;decltype(x)&gt;。 だから問題は:どのコンパイラーが正しいのか?の状態static_assertはに依存しているので、gccは正しいと思いますTが、よくわかりません。

1
バージョン間でC ++の式の型が変更されたのはなぜですか?
私はC ++の式のタイプを理解しようとしますが、C ++ドラフトを消化するのは非常に難しく、したがって他のリソースを好むので、読むほど混乱します。 C ++バージョン間の表現と定義が大幅に変更されています。 以下では、以下のドラフトを参照します。 C ++ 11 [ n3690 ](最終ドラフト) C ++ 17 [ n4659 ](最終ドラフト) C ++ 20 [ n4835 ](現在のドラフト) C++11 3.10左辺値と右辺値 ... prvalue(「純粋な」右辺値)は、x値ではない右辺値です。[例:戻り値の型が参照ではない関数を呼び出した結果は、prvalueです。12、7.3e5、trueなどのリテラルの値もprvalueです。—最後の例] C++17 3.10左辺値と右辺値 ... prvalueは、評価によってオブジェクトまたはビットフィールドを初期化するか、演算子のオペランドの値を、それが出現するコンテキストで指定されたとおりに計算する式です。 C++20 7.2.1値のカテゴリ* ... prvalueは、その評価がオブジェクトまたはビットフィールドを初期化する式、または演算子のオペランドの値を、それが出現するコンテキストまたはcv void型の式で指定されているように計算する式です。 言い回しの変更を理解し、いくつかの調整が行われますが、私にとっては定義全体が変更されます。誰かがこれを理解するのを手伝ってくれる?たとえば、prvalueがxvalueではないrvalueであるという文が削除されたのはなぜですか?または、なぜ役立つ例が削除されたのですか?
13 c++  c++11  c++14  c++17  c++20 

1
gccのあいまいな演算子
stlコンテナーの一部を印刷するための関数テンプレートを作成しました #include &lt;iostream&gt; #include &lt;vector&gt; #include &lt;string&gt; template &lt;template &lt;typename, typename&gt; class C, typename T, typename A&gt; std::ostream&amp; operator&lt;&lt;(std::ostream&amp; os, const C&lt;T, A&gt;&amp; container) { for (auto&amp; elem : container) { os &lt;&lt; elem &lt;&lt; " "; } return os; } int main() { std::vector&lt;std::string&gt; v { "One", "Two", "Three" …
13 c++  c++17 

1
プリミティブstatic_vector実装での未定義の動作の可能性
tl; dr:static_vectorの動作が未定義だと思いますが、見つかりません。 この問題はMicrosoft Visual C ++ 17にあります。この単純で未完成のstatic_vectorの実装、つまりスタック割り当て可能な固定容量のベクターがあります。これは、std :: aligned_storageとstd :: launderを使用するC ++ 17プログラムです。私はそれを問題に関連すると思われる部分にまで煮詰めようとしました: template &lt;typename T, size_t NCapacity&gt; class static_vector { public: typedef typename std::remove_cv&lt;T&gt;::type value_type; typedef size_t size_type; typedef T* pointer; typedef const T* const_pointer; typedef T&amp; reference; typedef const T&amp; const_reference; static_vector() noexcept : count() { } ~static_vector() …

2
コンパイル時にタイプ `const char *`の2つの文字列を連結することは可能ですか?
明らかに、constexpr関数内で2つの文字列リテラルを連結できますが、文字列リテラルと別の文字列リテラルを連結するとどうなるでしょうか。constexpr以下のコードのよう関数することはどうでしょうか。 template &lt;class T&gt; constexpr const char * get_arithmetic_size() { switch (sizeof(T)) { case 1: return "1"; case 2: return "2"; case 4: return "4"; case 8: return "8"; case 16: return "16"; default: static_assert(dependent_false_v&lt;T&gt;); } } template &lt;class T&gt; constexpr std::enable_if_t&lt;std::is_arithmetic_v&lt;T&gt;, const char *&gt; make_type_name() { const char * …
12 c++  c++17 

1
キャプチャレスラムダは標準で空であることが保証されていますか?
テンプレート関数で他のラムダから空の(キャプチャレス)ラムダを識別する方法を探しています。現在C ++ 17を使用していますが、C ++ 20の回答にも興味があります。 私のコードは次のようになります: template&lt;typename T&gt; auto func(T lambda) { // The aguments of the lambdas are unknown if constexpr (/* is captureless */) { // do stuff } } C ++標準(17または20)で、関数ポインターに変換可能なキャプチャレスラムダでもstd::is_empty歩留まりがtrueになることが保証されていますか? 例としてこのコードを見てください: auto a = []{}; // captureless auto b = [c = 'z']{}; // has captures …
12 c++  lambda  c++17  c++20 

1
std :: vectorがアライメントされたメモリを割り当てるための最新のアプローチ
次の質問には答えが古いしかし、関連、およびユーザーからのコメントされたマルク・Glisseは十分に議論されていない可能性があり、この問題に対する17 ++ C以来の新たなアプローチがあることを示唆しています。 すべてのデータにアクセスしながら、SIMDでアライメントされたメモリを適切に動作させようとしています。 Intelでは、タイプのfloatベクトルを作成し__m256、サイズを8分の1に削減すると、メモリが整列されます。 例えば std::vector&lt;__m256&gt; mvec_a((N*M)/8); 少しハックな方法で、ベクトル要素へのポインタを浮動小数点にキャストできます。これにより、個々の浮動小数点値にアクセスできます。 代わりに、私std::vector&lt;float&gt;はを正しく調整して、__m256segfaultingなしで他のSIMDタイプにロードできるようにしたいと思います。 私はaligned_allocを調べてきました。 これにより、正しく整列されたCスタイルの配列が得られます。 auto align_sz = static_cast&lt;std::size_t&gt; (32); float* marr_a = (float*)aligned_alloc(align_sz, N*M*sizeof(float)); ただし、これをどのように行うかわかりませんstd::vector&lt;float&gt;。のstd::vector&lt;float&gt;所有権を与えるmarr_a ことは可能ではないようです。 カスタムアロケーターを作成する必要があるという提案をいくつか見ましたが、これは多くの作業のように思われ、おそらく最新のC ++にはもっと良い方法がありますか?

1
修飾されていないsort()— std :: arrayではなくstd :: vectorで使用するとコンパイルされるのはなぜですか、どのコンパイラが正しいのですか?
呼び出すときstd::sort()にstd::array: #include &lt;vector&gt; #include &lt;array&gt; #include &lt;algorithm&gt; int main() { std::vector&lt;int&gt; foo{4, 1, 2, 3}; sort(begin(foo), end(foo)); std::array&lt;int, 4&gt; foo2{4, 1, 2, 3}; sort(begin(foo2), end(foo2)); } gccとclangの両方で、並べ替えのエラーが返されますstd::array-clang エラー:宣言されていない識別子 'sort'の使用; 「std :: sort」という意味ですか? std::sort(begin(foo2), end(foo2))問題を修正するための変更。 MSVCは、上記のコードを記述どおりにコンパイルします。 なぜ治療の違いの間std::vectorとstd::array、どのコンパイラが正しいですか?
11 c++  c++17 

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