C++相談室 part134

■ このスレッドは過去ログ倉庫に格納されています
2018/01/20(土) 09:05:42.21ID:mJKRg6iz0
次スレを立てる時は本文の1行目に以下を追加して下さい。
!extend:on:vvvvv:1000:512

C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE (VC++など)などの使い方の質問はその開発環境のスレにお願いします。

前スレ
C++相談室 part133
http://mevius.5ch.net/test/read.cgi/tech/1511509970/

このスレもよろしくね。
【初心者歓迎】C/C++室 Ver.102【環境依存OK】
http://mevius.5ch.net/test/read.cgi/tech/1509780815/

■長いソースを貼るときはここへ。■
 http://codepad.org/
 https://ideone.com/

[C++ FAQ]
https://isocpp.org/wiki/faq/
http://www.bohyoh.com/CandCPP/FAQ/ (日本語)
VIPQ2_EXTDAT: default:vvvvv:1000:512:----: EXT was configured
2018/01/20(土) 20:43:12.42ID:kYo2uzfm0
>>21
ムーブコンストラクタが定義されていないから

A(A &&) = default;
とでもしておけ。
2018/01/20(土) 20:49:44.91ID:w1mvJepJ0
>>22
ありがとうございます。解決しました。
24デフォルトの名無しさん (ワッチョイ 25b3-GP+B)
垢版 |
2018/01/20(土) 21:07:26.00ID:w1mvJepJ0
追加で質問させてください。

コンパイラが自動生成する関数で、noexceptがついているのは
・デストラクタ
・ムーブコンストラクタ
・ムーブアサインメントオペレーター
の3つでよろしいでしょうか。

よろしくお願いします。
2018/01/20(土) 21:11:18.68ID:Z4eZ5+gd0
残り3つもデータメンバと基底クラスの同じものが全部noexceptなら付くよ
26デフォルトの名無しさん (ワッチョイ 25b3-GP+B)
垢版 |
2018/01/20(土) 21:18:07.18ID:w1mvJepJ0
回答ありがとうございます。

データメンバと基底クラスのそれぞれのデフォルトコンストラクタが全て noexcept なら、
noexcept なデフォルトコンストラクタが自動生成される。
コピーコンストラクタ、コピーアサインメントオペレーターも同上
という理解でよろしいでしょうか。

また、その条件が成立しないときは、>>24で挙げた3つということになるのですしょうか。

よろしくお願いいたします。
27デフォルトの名無しさん (ワッチョイ 25b3-GP+B)
垢版 |
2018/01/20(土) 21:36:13.58ID:w1mvJepJ0
>>26について自己解決しましたので、質問を取り下げます。
ありがとうございました。
2018/01/21(日) 11:30:18.34ID:LU9Vj3hRM
>>16
noexceptなしに = defaultで宣言した場合はどうなるの?
2018/01/21(日) 11:32:32.53ID:LU9Vj3hRM
>>28
>> 25の間違いです
2018/01/21(日) 13:25:22.34ID:XRSBBZxr0
もちろん宣言通りになる
2018/01/21(日) 13:32:54.03ID:LU9Vj3hRM
>>30
thx
2018/01/21(日) 19:49:20.49ID:FwsOgvVZ0
記述上 int* であるが、上書きされた場合に自動的に中身を delete してくれるポインタの入れ物を、
operator= のオーバーロードなしで定義できますか?

ちょっと変な質問なのだけど、native C++なら多分以下コードで出来る。

struct PatHead {
int* ptr;
int* operator=(int* value){
if (ptr) delete [] ptr;
ptr = value;
return value;
}
operator int*(){ return ptr;}
};

void test(){
PatHead ph[10]; // int* ph[10] と同じ記述で通るのがミソ

ph[1] = (int*)1;
int* tgt1 = ph[1];
}

問題はこちらが使っているのはVC++/CLIで、
なぜか value struct では operator= のオーバーロードが出来ず、(C3194)
マネージ配列に直接入るのは value型だけなのでちょっと詰んでいる。
なお ref struct なら出来るのだが、こちらは逆に初期化部分で記述が増えるので、
それなら諦めようかな、って感じ。

というわけで回避策を思いつく人がいればお願いします。
何で値型で禁止されているか分かる人も居ればよろしく。
33デフォルトの名無しさん (ワッチョイ ae81-MBfL)
垢版 |
2018/01/26(金) 13:51:50.30ID:duEsoqcC0
イテレータでendの一つ前を表すのはありますか。
endからの引き算必須ですか。
2018/01/26(金) 13:58:16.53ID:SmrT25am0
&back()
2018/01/26(金) 14:00:31.27ID:27cZOHeHM
>>33
用途に合うかどうか分からないけど
rbegin, crbegin
2018/01/26(金) 14:14:09.94ID:duEsoqcC0
サンクスです。できました。
2018/01/27(土) 07:12:46.54ID:ZP0gkUPd0
rbeginはちょっとトリッキーな実装になってることがあるから注意
2018/01/27(土) 11:46:50.10ID:RraDQJG10
実装に依存しないような仕様に沿った使い方をすればいいんでないの?
仕様に合致していない実装ならどうしようもないが。
2018/01/27(土) 19:12:13.06ID:Boft2e8Ea
SHA256のハッシュをkeyにしたmapを高速で扱いたいんだが、
keyのoperator <,>それぞれでmemcmpしてて、多分このせいで性能悪くなってる

なんか良い解決策ってないですかね?
Linuxのrbtreeと比較すると100万件あたり150msec程度差がついてました
2018/01/27(土) 19:13:43.71ID:IajdzWB80
simd
2018/01/27(土) 19:44:42.49ID:MtS5alc90
unordered_mapにsha256の関数渡せばええやん
2018/01/27(土) 20:08:58.78ID:6QrTsC7zM
fpga
2018/01/27(土) 22:07:02.09ID:bqR9C45e0
mapじゃなくてハッシュを実装しろとしか
2018/01/27(土) 22:15:03.18ID:Im+FAy1Qa
>>40
便利そうだと思ったけど、データ構造的にアライメント揃えられないから使えなさそう

>>41
ソート済みデータを扱いたいパターンもあるので使えないです

コード的にさっくり改善する方法がなさそうなので
map諦めてそこだけ完全自作することにしました
レスしてくれた方々サンクスです
2018/01/27(土) 22:53:57.64ID:ZP0gkUPd0
Compareの自作で何がいけなかったのかわからないけど解決おめ
2018/01/27(土) 23:05:46.83ID:r2gR5oNyd
赤黒木ってスマートポインタを使って実装できますか?
親を弱参照で書いたらわけわかめに
2018/01/28(日) 01:55:54.91ID:B1112Jntd
ハッシュをソートかあ
2018/01/28(日) 03:22:06.75ID:vIDP+sWr0
コピーしたくないオブジェクトへのポインタ(ていうか全体をシリアライズするの可能性も考えたらindexがマジお勧め)の配列おソートすれば良い
そういった実装の詳細はクラスの中に隠すことができる 何のためにC++を使っているのやヽ(`Д´)ノ!!!11!1
2018/01/28(日) 08:17:39.92ID:abHZXNlp0
>>47
なんかモヤモヤするなそれw
2018/01/28(日) 11:41:38.50ID:/ypN0hd6M
>>39
hashは値に対してユニークじゃないけどいいの?
51デフォルトの名無しさん
垢版 |
2018/01/28(日) 14:41:11.23
そりゃハッシュ衝突用のフィールドくらい作ってるだろうよ
質問にないことは心配しなくていいよ
2018/01/28(日) 15:09:59.60ID:RaXbFAH70
心配してるんじゃなくてバカにしてるんだよw
2018/01/28(日) 15:44:58.16ID:C2Jb//yt0
バカにしようとして失敗してるとしか見えないけど w
2018/01/28(日) 20:33:36.08ID:NzqukFwp0
Impliment.h

class Impliment
{
public: base;
};


Interface.h

class Interface
{
2018/01/28(日) 20:42:03.84ID:NzqukFwp0
すいません。途中で書き込んでしまいました。

以下のようなクラスを作ったのですが、
derivedがImp::baseを継承しているため、
インクルードの順番が固定されてしまいます。(Impliment.hが先でないといけない)

こういったクラスは使う人から見て嫌がられるでしょうか。
ご意見をいただけるとありがたいです。

Impliment.h

class Impliment
{
public:
class base {}
};


Interface.h

template<class Imp>
class Interface
{
private:
class derived : public Imp::base {}
}
2018/01/28(日) 20:56:07.47ID:Xl/BPHGJ0
>>55
「XXの実装とインターフェイスが分かれている」ということをユーザが意識しないといけないのは抽象化の不足だと思う。
分離した形のデザインで開発するのはかまわないけど、ユーザに対してはなるべく隠すのが望ましい。

#include<Implement.h>
#include<Interface.h>

と書いたヘッダファイルを用意しておく程度のことでもだいぶんマシになる。
(インクルードガードはしておくこと)
2018/01/29(月) 02:50:08.46ID:gQcv+kbG0
>>55
普通は interface.h の冒頭で implement.h をインクルードしておく
2018/01/29(月) 05:39:18.37ID:+mqzfkB+0
>>55
このコードだけならインクルード順が逆でも問題ない。
2018/01/30(火) 20:17:26.27ID:fsahOVUj0
レスありがとうございます。

>>56
Implimentは複数あって、ユーザーが選ぶことができる
というのを想像して作っていました。

>>57
template化する前はそこでインクルードしていました。

>>58
たしかに、このコードだけでは大丈夫ですね。
正確にはこのコードだけではないので、他に原因があるのかもしれません。
ご指摘ありがとうございます。
2018/01/30(火) 21:08:08.01ID:VkcoBYQV0
Implement入れ替えさせたいならユーザーに適当な所で
template Interface<MyImplement>;
って書かせりゃいいだけじゃないの?
2018/01/30(火) 21:19:19.29ID:Lbh+cCVN0
typename imp::base
2018/02/04(日) 11:20:04.76ID:r6E1M8790
質問ですが
「このクラスはバイト列としてコピーできる」ということを明らかにするために
明示的にコピーコンストラクタを書くとして、
どう書けば処理系に依存することなくデフォルトのコピーコンストラクタ以上の性能になることを保証できますか
(もしくは、「このクラスはバイト列としてコピーできる」ということを明示する構文はありますか)
2018/02/04(日) 11:26:54.06ID:i7yJvuTcd
>>62
MyClass(const MyClass&) = default;
2018/02/04(日) 11:36:31.71ID:H9FebDBN0
デフォルトのコピーコンストラクタはメンバのコピーコンストラクタを起動するので、
そのクラス (に属するオブジェクト) 全体がバイト列としてコピーするわけではない。

trivially copyable class の要件を満たすように書けばバイト列としてコピー可能と保証される。
コンストラクタの書き方だけでは保証できない。
2018/02/04(日) 13:04:56.23ID:WecC8o2P0
memcpyするコピコンをユーザー定義すればええやん
2018/02/04(日) 13:46:35.82ID:r6E1M8790
>>63
なるほど「= default;」のありがたみがわかりた

>>64
なるほどそれだと安全性の点でイマイチ…
バイト列としてそのままリモートPCに送ったりするクラスに誰かが
バイト列としてのコピーが可能でないコードを追加したとしても
コンパイラで検出する術が無いっぽいように読める
2018/02/04(日) 13:47:37.01ID:r6E1M8790
訂正
誤:バイト列としてのコピーが可能でないコード
正:バイト列としてのコピーを不可能にするコード
2018/02/04(日) 13:47:46.54ID:HBpG+TPK0
>>62
std::is_trivially_copyable<T>がtrueになるように書いて
https://cpprefjp.github.io/reference/type_traits/is_trivially_copyable.html
トリビアル型とは何かは検索して
2018/02/04(日) 13:52:58.38ID:HBpG+TPK0
>>66
なおさらtype_traitsで条件に合わなければコンパイルを失敗させればよい
2018/02/04(日) 14:08:05.83ID:r6E1M8790
>>69
おk
2018/02/04(日) 16:47:05.72ID:H9FebDBN0
>>65
まあ書こうと思えば書けないことはないが、
やった結果に整合性がとれるかどうかは別問題なのでな……。
2018/02/04(日) 17:24:06.38ID:H9FebDBN0
流れをぶった切って質問するんだけど、
配列の一部をとる参照とかって作れない?
実際にはコンパイルが通らないけど、やりたいことはこんな感じ。

int a[3];
int (&b)[2] = static_cast<int (&)[2]>(a);
2018/02/04(日) 18:06:17.19ID:B+seqFts0
reinterpret_castすれば?
2018/02/04(日) 18:22:52.47ID:HJ1AdVlZ0
ポインタにして剥がせばいい
2018/02/04(日) 18:28:31.26ID:HBpG+TPK0
配列型はポインタではないので途中からとかない
2018/02/04(日) 18:55:06.41ID:i/oNqC3f0
一応うまく行ったけど規格で保証された挙動かどうかはよくわからない
https://ideone.com/wVzc6b
2018/02/04(日) 19:14:07.38ID:NcR26d4z0
でもポインタにしてしまうと困るシチュエーションなんてありうるの?
マクロの中でsizeofしてるとか?
2018/02/04(日) 20:30:26.18ID:WecC8o2P0
>>71
意味わかんねえ
どーゆーこと?
2018/02/05(月) 23:20:37.74ID:y5vbQcAP0
メンバのコピーコンストラクタを起動すべきところをmemcpy()しかしない手製コピーコンストラクタで済ませようとしたら破滅が訪れる

MyClass(const MyClass&) = default; なら勝手にやってくれるのでその心配が無いので安心
2018/02/05(月) 23:28:20.73ID:QTKEhMlZ0
しかしまあ >>68 なんていう便利なモノがあるとは
フラフラこういうスレ読んでるのもためになるなあ
2018/02/06(火) 07:54:17.35ID:CtmFRYuD0
>>79
>>62
2018/02/06(火) 08:05:48.85ID:cp/uvOeq0
>>62
処理系に依存することなく「保証」なんて出来ない
以上
2018/02/06(火) 08:27:38.08ID:rGp9SuaC0
>>63で解決している
もしくは以下への回答も>>69で出ている
2018/02/06(火) 09:14:20.61ID:CtmFRYuD0
バイト列コピーが = default; なわけねーだろアホ
2018/02/06(火) 11:45:28.85ID:rGp9SuaC0
よく読め
バイト列コピーでokの保証は>>69
遅くならないコンストラクタの書き方が>>63
2018/02/06(火) 11:48:04.39ID:rGp9SuaC0
そもそも「どうコンストラクタを書けば」ってのを質問してるんで
バイト列コピーでコンストラクタを書けってのは単に>>65の珍解答に過ぎない
2018/02/06(火) 11:51:41.68ID:CtmFRYuD0
すまんが日本語でたのむ
2018/02/06(火) 11:54:37.03ID:rGp9SuaC0
元の質問>>62
・処理系に依存せずデフォルトより遅くならないことが保証されているコンストラクタの書き方
もしくは
・バイト列コピーでokと明示する構文

だろ。
前者は>>63
後者は>>68-69
2018/02/06(火) 12:36:57.61ID:CtmFRYuD0
元質問: デフォルトのコピーコンストラクタ以上の性能
おまえ: デフォルトより遅くならないこと

よく読めをそのまま返す
2018/02/06(火) 12:57:03.34ID:bHMYZ9Vj0
以上っていうのは等しいかまたはそれを越えるという意味だぞ
2018/02/06(火) 14:01:35.47ID:rGp9SuaC0
そもそも memcpy は前者の性能保証も後者の仕様の保証もどちらも満たしてない
仕様が保証されてるなら多分性能的に大丈夫だろうという程度

間違いを認めると死ぬ病気なんだろうからもうこれ以上は言わない。
2018/02/06(火) 14:38:54.29ID:CtmFRYuD0
バイトコピーでmemcpyより高性能な手段を1つでも例示したらどうなんだ

> 間違いを認めると死ぬ病気なんだろうから

ああ、おまえがか
2018/02/06(火) 18:18:02.35ID:cp/uvOeq0
https://stackoverflow.com/questions/28623895/why-is-memmove-faster-than-memcpy
2018/02/06(火) 22:02:19.27ID:MckGyr3K0
memcpy()より速いコピー手段Xが仮にあったとして
論理的にmemcpy()で済むケースについてコンパイラが提供する
デフォルトのコピーコンストラクタがコピー手段Xにならない理由がわからん…

個人的には「=default;」と書いたら最高性能なんなら毎回手でmemcpy()とか書きたくないカンジ
2018/02/06(火) 22:06:49.77ID:CtmFRYuD0
>>94
class A {
public:
A() {}
A(A const&) { std::cout << "aho"; }
};

class B {
public:
A a;
B() = default;
};

int main()
{
B b, c = b; //this will call you.
}
2018/02/06(火) 22:09:42.68ID:MckGyr3K0
>>95は「論理的にmemcpy()で済むケース」では無いからちげう
2018/02/06(火) 22:29:22.47ID:CtmFRYuD0
だから日本語でたのむって言っただろ
2018/02/06(火) 22:29:24.08ID:MckGyr3K0
どうした?
訂正はよ
2018/02/06(火) 23:07:57.82ID:hdfY5rL3M
間違いを認めて・・・死んだのか?
2018/02/06(火) 23:21:41.18ID:MckGyr3K0
仕方ないので漏れが訂正するわ;
ttps://ideone.com/TZnGv4

↑のコードの
(*1)は「=default;」でデフォルトのコピコンの使用を明示
(*2)は手でmemcpy()でコピーするように書いたコピコン

次の条件で試したら(*1)も(*2)も同じコードになったわ
x86-64 gcc 7.2
-O2 -fno-strict-aliasing -std=c++14 -pedantic -Wall -Wextra

こことかで試せるが保存と公開方法がわからんかったのでideoneを使わせてもろうた
ttps://gcc.godbolt.org/

漏れの国語力ではようわからんが、さすがに多分>>84は間違いなんジャマイカ、
2018/02/06(火) 23:34:18.80ID:Ur4dB7lv0
Cから来た連中ってどうしてmemcpyやmemset使いたがるんだろうな
2018/02/07(水) 04:09:18.59ID:OAPGz/K+0
>>76
reinterpret_cast でなければ通らないときはだいたい駄目なときやわ。
2018/02/07(水) 04:22:37.75ID:OAPGz/K+0
>>100
「default がバイト列コピーとは『限らない』」という意味で >>84 は真。
2018/02/07(水) 05:00:09.29ID:1UF8v8gcM
開始アドレス、終了アドレス、サイズが64bit等で割り切れれば
バイトコピーより早いコピーはあるだろうね
105デフォルトの名無しさん
垢版 |
2018/02/07(水) 07:27:28.65
頭のいいコンパイラなら勝手にベクトル処理とかしてくれるんじゃないの?

知らんけど
106デフォルトの名無しさん (ワッチョイ 57b3-wbgk)
垢版 |
2018/02/07(水) 22:28:51.20ID:MTpdY7NJ0
"!"!"!MOHYO!"!"!"2"

1.[[[HUn≒MUL=POSI≠MAHO+Set*HUGE=SAGE=LOGE=NOISIA=0≒1]]]

2-[[[[[[[E=RAT%2^10%SPELAn!%]&!TOWA&!PEG#!NOLNOL8!#!HYAGO!2#]1*2=1]U]S]0]O]!#PAL!

3--->PAGODOL7&!@17,2222734.15&[[[%%RENRAK6,9,99"^10"]#$11.2%}]KAIJ]{

41.2SSS = RALQI2.β{{{RA4,0,238^97,1,$.S.L.E.I.L."Q5352.15Q"JOL"5*3>>>41.3q}}}>1.2<0
.3φTALHOSI"0">>>105.10<1.235<1.2>51≠52===55.632>V="E=0.835"of"1.32","632",0.683,1.end

{
2018/02/10(土) 19:52:35.19ID:x9I4Wn6Pd
C++では、
int i;
for (i = 0; i < 9; ++i) { ... }
が、
for (int i = 0; i < 9; ++i) { ... }
って書けるのは知っているだろう。( )の中で、変数を宣言できる。

だが、ifやwhileの( )の中で、変数を宣言できることを知らない人は多い。
2018/02/11(日) 04:31:12.99ID:9irhhPDg0
C++17では
if ( auto v = n; conditions ) {
...
}
が可能になるし、これからは広がってくれるかのう
2018/02/11(日) 06:11:03.22ID:l3GMmVaq0
>>108
これホント待ち遠しい
110デフォルトの名無しさん (ワッチョイ 4539-102K)
垢版 |
2018/02/11(日) 17:00:15.07ID:RGzNlubj0
それほど待ち遠しいか?
111デフォルトの名無しさん (ワッチョイ 99b3-7Au1)
垢版 |
2018/02/11(日) 17:27:44.93ID:QA9xO9uU0
待ち遠しくない
2018/02/11(日) 17:34:07.64ID:A61Ds/EIM
for( ) の制御変数はそのループでしか使わないことが多いから意味あったけど、if( ) でそんなケースはまれだしなぁ
あれば使うけど待ち遠しいって言うほどじゃない気がする
2018/02/11(日) 17:36:34.68ID:bT0HWvJB0
理想主義的な文法ですが、実効性はあるのか疑問ですね
2018/02/11(日) 17:40:12.67ID:KWDwqk940
一瞬意図が分からなかったが
()の中が;で区切れるという話?
2018/02/11(日) 17:41:52.24ID:rD0gl3AiM
dynamic_castとの組み合わせで使うとかどうよ
2018/02/11(日) 19:11:10.58ID:av7bQMHG0
結構あると思うけどね
if(DWORD err = GetLastError(); err != NO_ERROR)
この場合NO_ERRORが0だって分かってるから
if(DWORD err = GetLastError())
で済むから無意味だけど
2018/02/11(日) 19:17:28.82ID:yo2OB3cP0
>>116
前者の方が意図が明確だし意味はあると思う
118デフォルトの名無しさん
垢版 |
2018/02/11(日) 20:06:43.52
>>116
>if(DWORD err = GetLastError(); err != NO_ERROR)

普通こうやろ
if((DWORD err = GetLastError()) != NO_ERROR)

変数宣言は少しは意味あるかもしれんが(Perlと同じことができるってこと)
複文書けるのは特にメリット感じないわ
2018/02/11(日) 20:41:29.80ID:Ag9E1Urq0
それ通らんよ
こうだろ

DWORD err;
if((err = GetLastError()) != NO_ERROR)

if内でしか使わないerrが外部に漏れてるのがよろしくないってこと
120デフォルトの名無しさん
垢版 |
2018/02/11(日) 20:56:03.30
>>119
それが通るという変更だと思ってたわ

こう書けるPerlのほうがまだ優位性あるね

if((my $err = GetLastError()) != NO_ERROR)
2018/02/11(日) 22:10:23.49ID:p+z832PL0
if(init ; expr)だと初期化と式が関連していなくてもいいので>>120とは違う構文になる
だからこんなのでもよい
if(int err = GetLastError(); hoge.aho())

lock_guardもしておける
if(std::lock_guard<std::mutex> lock(m); flag)

構造化束縛も使える
if(auto [a, b, c] = f(); b > c){ std::cout << "b > c" << std::endl; }
122デフォルトの名無しさん (ワッチョイ ddc3-saCW)
垢版 |
2018/02/12(月) 12:22:30.52ID:sATukCOa0
Cでは名前空間っていうのをすごい扱っていた気がするんだけどC++は名前空間扱うことってないの?
一つのアプリケーションも完成させたことがないど素人の質問ですまんが
■ このスレッドは過去ログ倉庫に格納されています
5ちゃんねるの広告が気に入らない場合は、こちらをクリックしてください。

ニューススポーツなんでも実況