C++相談室 part134
■ このスレッドは過去ログ倉庫に格納されています
次スレを立てる時は本文の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 STLつかうと一気に実行ファイルサイズが10倍に?!
環境によるだろ。
俺はBorland-C++5.6.2に -D_RTLDLL オプションを指定して、極力
ランタイムを使用するようにして使っているが、例えばstd::vectorを
使っても使わない時と比べ10Kほどしか増えない
すげえ。ダイナミックリンクしといてファイルサイズが増えないとかいってるよ。この人。
C1010: プリコンパイル済みヘッダーの検索中に予期しない EOF を検出しました。
とかいうエラーが出るんだけどこれってどうすればいいの?
#include <stdafx.h>
後死ね。
言葉が悪いな。それで教えているつもりか。
まぁヒントぐらいにはなったな。
うむごくろう。
いつまでこの糞テンプレ張り続けるんだおい
---- テンプレ ここまで ---- 前スレのvectorのsize_tの質問した者だけど
実際gprofでvectorの[]が重い原因になってることを確認してる
次に重い原因がイテレータの比較なんだけど >>3
> 実際gprofでvectorの[]が重い原因になってることを確認してる
どんな確認したのか知らんけど、確認しててあんな質問してるなら単なるバカとしか思えないが... メモリ帯域が律速になる処理はわりとあるので
大容量のデータを処理してるならおかしくはない
キャッシュ効かないメモリアクセスするコストに比べたら整数の拡張など微々たるもんだ >>1乙
↓前スレの続き
std::vector<double> vec((size_t)1000);
...
size_t sz = vec.size();
for (int i = 0; i < (int)sz; ++i) {
cout << i << " " << vec[i] << "\n";
}
の方がiをsize_tにするよりループ命令の部分が軽量化されることにより早いかも試練(x64では気のせい?
およびループ内で他に32 bit演算をやる場合、x64だと全てレジスタ上で賄える可能性が高まるから
速くなるかも試練、
結論: アセンブリコードを確認せよ いやスマン
例が不適切やったわ;
ループ内でstd::coutみたいな重量のある関数呼び出しをしたら
「全てレジスタ上で賄える」とか
「キャッシュが有効活用で劇速化」とかも糞も無いな noexceptってどういうときにつけたらいいですか。 >>3
[ ] が問題なら生ポ使えと書いてるんだけど無視? >>8
重量の有り無しの前に
数値の文字列変換がsize_tとintじゃ違うだろ
それがなければどっちでも変わらんよ
64bit環境ならレジスタも64bitなんで >>3
ん?
プロファイラの確認?
だとしたら[ ] が遅いんじゃなくてメモリの読み込みが実際に遅い可能性があるのでは?
そもそも、
[ ] が問題になるような小さなループで
[ ] の時間を正しく測れるのか?
いずれにしろ、生ポと比較してみるのが一番 メモリ帯域の問題なら
もっと大きな視野で最適化をしないとな
複数ループをくっつけてメモリアクセスを減らすとか
細切れに処理をしてキャッシュを効かすとか []が問題になるわけ無いだろ。ソースコード見たのかよ。
ナマポで書き直すなんて無意味。抜本的にアルゴリズム見直せ あ、可能性だけで言えば
signedよりunsignedの方が速い
32bit から 64bit の符号拡張はコストが微妙にかかることもあるが、
ゼロ拡張はなにもしなくて良いから
レジスタの上位32bitは勝手にゼロになる >>14
問題になることもある
君こそソースを見たかな? >>15
今時のプロセッサでそんな奴見たことないけど?
妄想じゃないなら具体例よろしく >>17
そんなやつって何だ?
符号拡張にコストがかかってゼロ拡張にコストがかからない例ならx86-64がそうだが 32bitデータをレジスタに書き込んだら上位32bitが0クリアされることを言ってるんでしょ
コスト0って言うのはどうかと思うけど 質問させてください。
以下のコードで push_back 時にコピーコンストラクタが呼ばれます。
ttps://ideone.com/Zodd94
こちらとしては、下のページにあるように、ムーブコンストラクタが呼ばれることを期待しています。
ttps://qiita.com/_meki/items/90f9815a1e899593daa3
なぜムーブではなくてコピーになるのか、教えて頂けないでしょうか。 >>21
ムーブコンストラクタが定義されていないから
A(A &&) = default;
とでもしておけ。 追加で質問させてください。
コンパイラが自動生成する関数で、noexceptがついているのは
・デストラクタ
・ムーブコンストラクタ
・ムーブアサインメントオペレーター
の3つでよろしいでしょうか。
よろしくお願いします。 残り3つもデータメンバと基底クラスの同じものが全部noexceptなら付くよ 回答ありがとうございます。
データメンバと基底クラスのそれぞれのデフォルトコンストラクタが全て noexcept なら、
noexcept なデフォルトコンストラクタが自動生成される。
コピーコンストラクタ、コピーアサインメントオペレーターも同上
という理解でよろしいでしょうか。
また、その条件が成立しないときは、>>24で挙げた3つということになるのですしょうか。
よろしくお願いいたします。 >>26について自己解決しましたので、質問を取り下げます。
ありがとうございました。 >>16
noexceptなしに = defaultで宣言した場合はどうなるの? 記述上 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 なら出来るのだが、こちらは逆に初期化部分で記述が増えるので、
それなら諦めようかな、って感じ。
というわけで回避策を思いつく人がいればお願いします。
何で値型で禁止されているか分かる人も居ればよろしく。 イテレータでendの一つ前を表すのはありますか。
endからの引き算必須ですか。 >>33
用途に合うかどうか分からないけど
rbegin, crbegin rbeginはちょっとトリッキーな実装になってることがあるから注意 実装に依存しないような仕様に沿った使い方をすればいいんでないの?
仕様に合致していない実装ならどうしようもないが。 SHA256のハッシュをkeyにしたmapを高速で扱いたいんだが、
keyのoperator <,>それぞれでmemcmpしてて、多分このせいで性能悪くなってる
なんか良い解決策ってないですかね?
Linuxのrbtreeと比較すると100万件あたり150msec程度差がついてました unordered_mapにsha256の関数渡せばええやん >>40
便利そうだと思ったけど、データ構造的にアライメント揃えられないから使えなさそう
>>41
ソート済みデータを扱いたいパターンもあるので使えないです
コード的にさっくり改善する方法がなさそうなので
map諦めてそこだけ完全自作することにしました
レスしてくれた方々サンクスです Compareの自作で何がいけなかったのかわからないけど解決おめ 赤黒木ってスマートポインタを使って実装できますか?
親を弱参照で書いたらわけわかめに コピーしたくないオブジェクトへのポインタ(ていうか全体をシリアライズするの可能性も考えたらindexがマジお勧め)の配列おソートすれば良い
そういった実装の詳細はクラスの中に隠すことができる 何のためにC++を使っているのやヽ(`Д´)ノ!!!11!1 >>39
hashは値に対してユニークじゃないけどいいの? そりゃハッシュ衝突用のフィールドくらい作ってるだろうよ
質問にないことは心配しなくていいよ バカにしようとして失敗してるとしか見えないけど w Impliment.h
class Impliment
{
public: base;
};
Interface.h
class Interface
{ すいません。途中で書き込んでしまいました。
以下のようなクラスを作ったのですが、
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 {}
} >>55
「XXの実装とインターフェイスが分かれている」ということをユーザが意識しないといけないのは抽象化の不足だと思う。
分離した形のデザインで開発するのはかまわないけど、ユーザに対してはなるべく隠すのが望ましい。
#include<Implement.h>
#include<Interface.h>
と書いたヘッダファイルを用意しておく程度のことでもだいぶんマシになる。
(インクルードガードはしておくこと) >>55
普通は interface.h の冒頭で implement.h をインクルードしておく >>55
このコードだけならインクルード順が逆でも問題ない。 レスありがとうございます。
>>56
Implimentは複数あって、ユーザーが選ぶことができる
というのを想像して作っていました。
>>57
template化する前はそこでインクルードしていました。
>>58
たしかに、このコードだけでは大丈夫ですね。
正確にはこのコードだけではないので、他に原因があるのかもしれません。
ご指摘ありがとうございます。 Implement入れ替えさせたいならユーザーに適当な所で
template Interface<MyImplement>;
って書かせりゃいいだけじゃないの? 質問ですが
「このクラスはバイト列としてコピーできる」ということを明らかにするために
明示的にコピーコンストラクタを書くとして、
どう書けば処理系に依存することなくデフォルトのコピーコンストラクタ以上の性能になることを保証できますか
(もしくは、「このクラスはバイト列としてコピーできる」ということを明示する構文はありますか) >>62
MyClass(const MyClass&) = default; デフォルトのコピーコンストラクタはメンバのコピーコンストラクタを起動するので、
そのクラス (に属するオブジェクト) 全体がバイト列としてコピーするわけではない。
trivially copyable class の要件を満たすように書けばバイト列としてコピー可能と保証される。
コンストラクタの書き方だけでは保証できない。 memcpyするコピコンをユーザー定義すればええやん >>63
なるほど「= default;」のありがたみがわかりた
>>64
なるほどそれだと安全性の点でイマイチ…
バイト列としてそのままリモートPCに送ったりするクラスに誰かが
バイト列としてのコピーが可能でないコードを追加したとしても
コンパイラで検出する術が無いっぽいように読める 訂正
誤:バイト列としてのコピーが可能でないコード
正:バイト列としてのコピーを不可能にするコード >>66
なおさらtype_traitsで条件に合わなければコンパイルを失敗させればよい >>65
まあ書こうと思えば書けないことはないが、
やった結果に整合性がとれるかどうかは別問題なのでな……。 流れをぶった切って質問するんだけど、
配列の一部をとる参照とかって作れない?
実際にはコンパイルが通らないけど、やりたいことはこんな感じ。
int a[3];
int (&b)[2] = static_cast<int (&)[2]>(a); 一応うまく行ったけど規格で保証された挙動かどうかはよくわからない
https://ideone.com/wVzc6b でもポインタにしてしまうと困るシチュエーションなんてありうるの?
マクロの中でsizeofしてるとか? メンバのコピーコンストラクタを起動すべきところをmemcpy()しかしない手製コピーコンストラクタで済ませようとしたら破滅が訪れる
MyClass(const MyClass&) = default; なら勝手にやってくれるのでその心配が無いので安心 しかしまあ >>68 なんていう便利なモノがあるとは
フラフラこういうスレ読んでるのもためになるなあ >>62
処理系に依存することなく「保証」なんて出来ない
以上 >>63で解決している
もしくは以下への回答も>>69で出ている バイト列コピーが = default; なわけねーだろアホ よく読め
バイト列コピーでokの保証は>>69
遅くならないコンストラクタの書き方が>>63 そもそも「どうコンストラクタを書けば」ってのを質問してるんで
バイト列コピーでコンストラクタを書けってのは単に>>65の珍解答に過ぎない 元の質問>>62は
・処理系に依存せずデフォルトより遅くならないことが保証されているコンストラクタの書き方
もしくは
・バイト列コピーでokと明示する構文
だろ。
前者は>>63
後者は>>68-69 元質問: デフォルトのコピーコンストラクタ以上の性能
おまえ: デフォルトより遅くならないこと
よく読めをそのまま返す 以上っていうのは等しいかまたはそれを越えるという意味だぞ そもそも memcpy は前者の性能保証も後者の仕様の保証もどちらも満たしてない
仕様が保証されてるなら多分性能的に大丈夫だろうという程度
間違いを認めると死ぬ病気なんだろうからもうこれ以上は言わない。 バイトコピーでmemcpyより高性能な手段を1つでも例示したらどうなんだ
> 間違いを認めると死ぬ病気なんだろうから
ああ、おまえがか memcpy()より速いコピー手段Xが仮にあったとして
論理的にmemcpy()で済むケースについてコンパイラが提供する
デフォルトのコピーコンストラクタがコピー手段Xにならない理由がわからん…
個人的には「=default;」と書いたら最高性能なんなら毎回手でmemcpy()とか書きたくないカンジ >>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.
} >>95は「論理的にmemcpy()で済むケース」では無いからちげう 仕方ないので漏れが訂正するわ;
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は間違いなんジャマイカ、 ■ このスレッドは過去ログ倉庫に格納されています