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がそうだが MOVSXもMOVZXも0クロックでは処理できないと思うんだが
ZXが0クロックで出来るってエビデンスはあるのかな?
32bitデータをレジスタに書き込んだら上位32bitが0クリアされることを言ってるんでしょ
コスト0って言うのはどうかと思うけど
>>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は値に対してユニークじゃないけどいいの? 51デフォルトの名無しさん2018/01/28(日) 14:41:11.23
そりゃハッシュ衝突用のフィールドくらい作ってるだろうよ
質問にないことは心配しなくていいよ
バカにしようとして失敗してるとしか見えないけど 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);
でもポインタにしてしまうと困るシチュエーションなんてありうるの?
マクロの中でsizeofしてるとか?
メンバのコピーコンストラクタを起動すべきところをmemcpy()しかしない手製コピーコンストラクタで済ませようとしたら破滅が訪れる
MyClass(const MyClass&) = default; なら勝手にやってくれるのでその心配が無いので安心
しかしまあ >>68 なんていう便利なモノがあるとは
フラフラこういうスレ読んでるのもためになるなあ >>62
処理系に依存することなく「保証」なんて出来ない
以上 バイト列コピーが = 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()で済むケース」では無いからちげう 仕方ないので漏れが訂正するわ;
https://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を使わせてもろうた
https://gcc.godbolt.org/
漏れの国語力ではようわからんが、さすがに多分>>84は間違いなんジャマイカ、 Cから来た連中ってどうしてmemcpyやmemset使いたがるんだろうな
>>76
reinterpret_cast でなければ通らないときはだいたい駄目なときやわ。 >>100
「default がバイト列コピーとは『限らない』」という意味で >>84 は真。 開始アドレス、終了アドレス、サイズが64bit等で割り切れれば
バイトコピーより早いコピーはあるだろうね
105デフォルトの名無しさん2018/02/07(水) 07:27:28.65
頭のいいコンパイラなら勝手にベクトル処理とかしてくれるんじゃないの?
知らんけど
"!"!"!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
{ C++では、
int i;
for (i = 0; i < 9; ++i) { ... }
が、
for (int i = 0; i < 9; ++i) { ... }
って書けるのは知っているだろう。( )の中で、変数を宣言できる。
だが、ifやwhileの( )の中で、変数を宣言できることを知らない人は多い。
C++17では
if ( auto v = n; conditions ) {
...
}
が可能になるし、これからは広がってくれるかのう
for( ) の制御変数はそのループでしか使わないことが多いから意味あったけど、if( ) でそんなケースはまれだしなぁ
あれば使うけど待ち遠しいって言うほどじゃない気がする
理想主義的な文法ですが、実効性はあるのか疑問ですね
一瞬意図が分からなかったが
()の中が;で区切れるという話?
dynamic_castとの組み合わせで使うとかどうよ
結構あると思うけどね
if(DWORD err = GetLastError(); err != NO_ERROR)
この場合NO_ERRORが0だって分かってるから
if(DWORD err = GetLastError())
で済むから無意味だけど
>>116
前者の方が意図が明確だし意味はあると思う 118デフォルトの名無しさん2018/02/11(日) 20:06:43.52
>>116
>if(DWORD err = GetLastError(); err != NO_ERROR)
普通こうやろ
if((DWORD err = GetLastError()) != NO_ERROR)
変数宣言は少しは意味あるかもしれんが(Perlと同じことができるってこと)
複文書けるのは特にメリット感じないわ それ通らんよ
こうだろ
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) 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; } Cでは名前空間っていうのをすごい扱っていた気がするんだけどC++は名前空間扱うことってないの?
一つのアプリケーションも完成させたことがないど素人の質問ですまんが
>>122
まずは"C"の入門書を読んで、何を見間違えたのかはっきりさせてからにしようか。 構造体タグと型名の名前空間が分かれているといったような意味での名前空間は C に有るが
C++ では構造体タグはそのまま型名としても使えるし、そういう意味での名前空間の話かな?
こんな名前空間もあるね
int x;
int main(void)
{
x = 1;
int x;
x = 2;
{
int x;
x = 3;
}
return 0;
}
謎すぎワロタがそこから上のスコープのxを参照してくれ
std::mapのように文字列や構造体をキーにした高速アクセスができて、
要素の数が一定数を超えたらLRU形式で勝手に削除してくれる、
キャッシュのような機能を実装したいのだけど、
C++でそのような仕組みを作れるクラスはないですか?
自分で実装するならどうにでもなるだろ
そのための道具は全て標準で揃っている
バックグラウンドならスレッド使うしかないんじゃないかな
C++のプログラマーって性格ねじ曲がってるなあ
初めてGo応援したくなったわ
>>137
どんな点が、性格悪い、と思わせるのですか? >>136
要素数が閾値を超えるのは要素が追加される時だからその時に古い奴を削除すりゃいいだけじゃね? >>135
簡単で良いのでサンプルコード書いてもらえませんか? >>135じゃないけどシンプルにいくなら
{
map<key,value> data; // 本来のデータ
map<key,list<key>::iterator> lruindex; //
list<key> lrulist; // LRUリスト
... // mapと同じインターフェイス
}
みたいなクラスで要素の追加・削除・参照とかの時にLRUリスト見て処理すればいい 辞書・線形リスト・2分木を、組み合わせる。Ruby で書くと、
class LRU_hash
def initialize (max_size = 3)
# ary は、hash に追加・アクセスした順
@hash = {}; @ary = []
@max_size = max_size
end
def push (key)
if @hash.has_key? key
# 一旦、要素を削除してから、最後尾に追加しなおす
@ary.delete key
else
if @max_size == @hash.size
# 先頭要素を削除してから、最後尾に追加する
@hash.delete(@ary.shift)
end
@hash[key] = true
end
@ary.push key
end
def print_buf
puts @ary.join ', '
end
end
ary = ["あ", "a", "あ", "い", "b", "あ", "c"]
hash = LRU_hash.new 4
ary.map { |key| hash.push key }
hash.print_buf #=> い, b, あ, c
145デフォルトの名無しさん2018/02/16(金) 04:31:51.17
>>144
> # ary は、hash に追加・アクセスした順
参照のたびに最後尾に追加しなおすの? プログラムを作っていて困っています。
プログラム動作環境、windows 7 x86_x64
プロセスをExplorerを親として、
起動したプロセスにファイルの存在するディレクトリを作業ディレクトリとして
割り当てたい。
ただし、プロセスへのアタッチによる変更は禁止とする。
ようするにファイルをダブルクリックして起動するのと同じ状況を再現したいのです。
例
C:\hoge\fuga.exe
[現状]
Explorer C:\hoge\fuga.exe
親
explorer.exe
カレントディレクトリ
C:\Windows\System32\
[理想]
Explorer C:\hoge\fuga.exe
親
explorer.exe
カレントディレクトリ
C:\hoge\
>>145
>>134
で、LRU と書いてあるから、Hash に追加しようとした度に、
すでに存在する場合でも、配列の最後尾に追加しなおした
どういう意味か、正確にはわからないけど >>146
explorer.exeへのショートカットを作ってプロパティで作業ディレクトリを指定するか、
COMでIShellLink::SetWorkingDirectoryを使って同じことをするあたりか? みなさんありがとうございます。
std::mapにLRUや最大要素数の仕組みを持たせた派生クラスでも
無いかと思ったのですが、標準ではやっぱり無いですか。
>>143のように、std::mapをメンバの一つに持たせた独自クラスを
一から作っていくことになるんですかね。 >>149
「c++ lru map」でググったか?
いくつかサンプルになりそうなコードが見つかるんだけど C++を勉強しようと思ってる者ですが書籍を探しております。Cはある程度書けるのでそれを前提とした書籍が欲しいです
C++ クイック入門&リファレンス
プログラミング言語C++ 第4版
>>155
C++11 以前だが accelerated c++, ここでフォローするよ こっちはフッサフサやで 以下のようにconst char*型の文字列でchar*型の変数を初期化したいときに
strcpyやstrlenを書かずにstd::stringを利用して短くかけないかと思うのですが
msvcだとエラーにならず、clang, gccだとdeleteでセグメンテーション違反になります。
どうすればより良い感じになるでしょうか?const_castはできれば使いたくないです。
#include <string.h>
#include <string>
#include <iostream>
int main()
{
const char* asdf = "asdf";
// char* psz2 = new char[strlen(asdf)+1];
// strcpy(psz2, asdf);
std::string *psz = new std::string(asdf);
char* psz2 = &(*psz)[0];
std::cout << psz2 << std::endl;
delete psz2;
return 0;
}
delete psz2なんてしちゃだめconst関係ない
何故stringそのものじゃなくて内部データをdeleteしようと思ったのか
newで確保した配列じゃないからdeleteはできない
stringの内部データは静的な配列と動的な配列を組み合わせて表現されている
mscvの場合先頭16文字はchar[16]でそれ以降は動的な配列に入るようになっている
psz[0]のアドレスはchar[16]の先頭アドレスなので当然deleteできない
msvcはdeleteに失敗しても落ちないのかな
>>155-159
本格的な本なら、ロベール、ハーバート・シルトの独習
軽めの本なら、柴田 望洋、林 晴比古、猫 ハンガリー人まだ絶滅してないのか。
stringはnull terminatedでないからpszはおかしい。
psz2もnull terminatedの保証がないからc_strを使うべき。
うまくいったらstrdupも調べとこうな。
>>162
char* psz2 = &(*psz)[0]; って
char* psz2 = psz->c_str(); と同じなのかな?
いずれにせよ delete psz; は出来る(するべき?)だけど、
delete psz2; は出来ないんじゃないかな。 必要ないところでnew/delete使う人は根本からして何も分かってない
>>162
お前はstringがただの配列だと思っているのか?
このトンチキ野郎! >>162
弁護士の唐沢です
しっかり「char* const」と「const char*」の違いを認識しなさい
const char*は参照先の定数を変更しない事を保証する宣言であり、char*は参照先の定数を変更できる為、const char*で保持するアドレスをchar*にコピーする事は言語仕様により禁止されています。それは分かるよね?
最初に宣言したポインタを間違えて別アドレスで上書きしないようにconstで固定したいのなら、char* constを使うようにしましょう。とりあえずとりいそぎ >>162
strdupという手があるが何がしたいのか今一つ分からない
const char* asdf = "asdf";
char *p = strdup(asdf);
std::cout << p << std::endl;
delete p; >>167
データは連続しているので同じになる
16文字まではスタックを使い、それ以上の長さになるとヒープにコピーされる
実装ではメンバの配列には何かしらのエスケープ文字が入る
ちなみにmsvcでは実装の都合上free(&str[0])で強引に解放できる 補足
スタックとヒープを使い分けるかどうかは実装依存
gcc、clang、msvcでは行われている
したがって短い文字列でnewを避けるためにstringを使わないというのは意味が無い
175デフォルトの名無しさん2018/02/17(土) 18:06:03.81
>>171
strdupで確保した領域をfreeでなくdeleteするのは正しいの? >>175
弁護士の唐沢です
mallocとdeleteは併用厳禁です。freeを使用してください >>162
ぶっちゃけた話、 strcpy が一番短いと思う。 183デフォルトの名無しさん2018/02/17(土) 18:59:50.35
>>182
strdup という答えが出てるのに何言ってるの? >>183
strdup は C++ の仕様の範囲内ではないので……。
POSIX と MSVCRT に有るからほとんどの場合に十分といえば十分なのかもしんないけど。 strdup()だと明示的に開放コードをどっかに書かなくてはならなくて必ず忘れるので
せっかくC++なのでスマポ的にwrapすると良いと思う
ホワイトボックスなCでは許せるが
ブラックボックスなC++の流儀には全く合わない
それがstrdup
>>173-174 教えてくれてありがとう。
返されるアドレスは等しい値なのか、という単純な質問だったんだけど、
読み直してみたら分かりにくい質問文だと思っていた次第。
それにしても &(*psz)[0] って結構ややこしいのね。
オーバーロードされた[]演算子が返すcharへの参照、
に対してアドレス演算子&を作用させた結果、て感じかな。 すみません、たくさんレスありがとうございます。
_strdupにしてみたら期待の動作ができました。
ありがとうございました。
また質問してすみません。
msvc(vs2017)だとコンパイラをC++17にしても以下のプログラムで
C2664 'void (T *&)': 引数 1 を 'hoge *' から 'hoge *&' へ変換できません。
となってしまうのですが、コードにバグが有るでしょうか?msvcのバグでしょうか?
GCCやClangではコンパイルできます。
#include <memory>
struct hoge {};
template <class T>
inline void safe_delete(T*& p) {
if (p) {
delete p;
p = nullptr;
}
}
int main() {
std::unique_ptr<hoge, decltype(&safe_delete<hoge>)> sp{new hoge(), safe_delete<hoge>};
return 0;
}
(T *&)
そもそも、ポインタ・参照を、同時に使えるのか?
new hoge()は変数じゃないから、代入できない。
>>165
独習C++ はいいですね、特に演習問題「std::stringを再実装する」を絶賛します
これが書けるようになったらC++初級者をかたってもいいかもしれない、もしかすると解答は載ってなかったかもしれないけれども >>185
どこから引用したのか知らんけど、そのページ読んでないだろ…
システムハンガリアンはまるで役に立たないって書いてあるぞ。 >>194
(システム)ハンガリアンってそんなに悪いものなんですかねえ
いや、win32api がバンバンハンガリアンしているので、そんなもんか、と思っていましたが >>195
OOPともTMPとも型推論とも相性が悪いからね。
MS自身ももう使うなって言ってる。 嫌いだからハンガリアン意地でも使わなかった
dwやらszやらせっかくのフリーフォーマッとが台なしだよ
>>191
それは「ポインタ変数の参照」で、たしか便利に使えた気がしますが…
明日にでもちょっと書いてみます、今日は疲れました… >>195
システムハンガリアンは弊害ばかりだろうけど、アプリケーションハンガリアンは適切に使えば有益だよ。 mとかいらなくねってなって削ったら_から始まるようになった
データの属性としてサイズとか型そのものを明示したいときはシステムハンガリアンするしかないし、
よってWIN32APIがシステムハンガリアンを使って定義されるのは全く正しい
問題なのはアプリケーションハンガリアンすべきときと
システムハンガリアンすべきときが区別できない香具師が適当に使うと
被害甚大だということやがな…
今時システムハンガリアンは無いだろ
20年前で時間が止まってるのかよ
>>205
なぜシステムハンガリアンが有り得ないのかkwsk
DWORDを渡すABIがある日突然気まぐれにUSHORTに変わったりしたら困りはしまいか ググればいいだろ
積極的批判
システムハンガリアンを使っているソースコードを修正してデータ型を変更した際、同時に変数名も変更するコストがかかる。変更を怠ると、たちまち不整合となり、保守の障害となるだけで一利もない。
C++やC#のような言語では型付けが存在するためにシステムハンガリアンを使用することによる利点はない[3]。
移植性を阻害する。
総称型、メタプログラミングとの相性が悪い。
消極的批判
いわゆる良書と呼ばれるようなC++本で、現在[いつ?]システムハンガリアンを採用している例が皆無。
かつてWindows API/MFCにおいてハンガリアンを全面的に採用していたMicrosoft自身が、.NET Frameworkではハンガリアンを禁止[1]している。
型なんてマウスオーバーなりすれば表示されるだろ
変数名に書いておかなきゃわからないとかメモ帳で書いてるのかよ
>>190
デリータはポインタが指す先のリソースを後始末するのが仕事であって、
ポインタが無効になるという処理は unique_ptr の側でやってくれるので、
ヌルを代入する必要はない。
むしろ unique_ptr 内で管理しているものをデリータが勝手に弄るのは好ましくないので、
参照で受けるのはやめてさしあげろ。
私なりに仕様を読んでこの場合をエラーにする根拠は発見できなかったが、
エラーになってくれる方がありがたい場面だと思う。 デリータに渡されるのは左辺値と限らないからだろう。
N3337 だと 516 ページの説明がデリータの要件だと思うんだけど、
デリータ d の型が D で ptr の型が unique_ptr<T, D>::pointer のとき式 d(ptr) が valid であることと書いてあって、
ptr が rvalue か lvalue かってのは特に指定がない。 (どこかに書いてあったりする?)
この説明で言ってる ptr が変数名なのだとしたら暗に lvalue とほのめかしてるようにも思えなくもないし、よくわからん。
わからんことは避けて通りたい。
私なりの見解としては未定義だと思ってる。
未定義ならばやったらエラーになる方向にしてくれる方がありがたいという思い。
>>206
ABIにシステムハンガリアン関係ないだろ…
APIを指してるとして、呼び出し側はリファレンスマニュアルなりIDE機能なりを利用して引数の型情報も
システムハンガリアンが付いている仮引数名と同時に参照しているはずだよね?情報重複してるけど本当に必要?
仮引数名のシステムハンガリアンの有無に関わらず、APIのシグネチャは用意に変更してはならないものだけど、
そもそも仮引数名はシグネチャじゃないからシステムハンガリアンがついていたって何の保証にもならないよ? 重複する情報をコンパイラの支援なく一致させ続けることが出来るだろうか。 いや、できない。
って話よね。
まあ世の中にはそういうのを検査するツールとかもあるんだろうけどさぁ、
そういうツールを導入できる環境ならまともな IDE だって使えるだろう。
>>210
>>211
レスありがとうございます。
shared_ptrだと行けるのでなんかすればコンパイル通るのではないかと
思ったのですがだめなんですね〜。
普通に使う用とカスタムデリータに使う用と二種類用意してやり過ごしてみたいと思います。
template <class T>
inline void safe_release(T*& p) {
if (p) {
p->Release();
p = nullptr;
}
}
template <class T>
inline void custom_deleter(T* p) {
p->Release();
// p = nullptr; no meaning
} >>207
藻前はレスをきちんと読んでいないのではないか
>システムハンガリアンを使っているソースコードを修正してデータ型を変更した際、同時に変数名も変更するコストがかかる。(>>207)
に直接対応する元レス>>206は、
>データの属性としてサイズとか型そのものを明示したいとき(>>204)
について述べているのでデータ型変更時のコストを言い立てても批判にならない
消極的批判については、アプリケーションハンガリアンすべきときと システムハンガリアンすべきときが
区別できない香具師の的外れな批判がクソウゼーからそうなったのかもしれん、
(ちな両者を区別できない香具師への警戒も>>204で言及済み >>214
十分賢いIDEが人間のミスを完璧に排除してくれるんならそうかもしれんが
システムハンガリアンをしてはいけないという積極的理由にはやはりならないのであった
それとも「間違ったコードは間違って見えるようにする 」(>>185)の効能を全否定する?
APIの定義は変わらなくとも、それを利用するソースコードがころころ変わり得るわけで、
byStrLength
にある日だれかがDWORD型の値を突っ込んだとしたら…
こういうケースを考えたら、「接頭辞を見ればデータ内容の属性がワカルというメリット(>>185)」は
ありえないぐらい賢いIDEでも使わないと他に代え難いと思うがどうか、
>>198
>嫌いだからハンガリアン意地でも使わなかった
おk ようやく建設的な議論に着手できる、 あり得ないくらいバカなプログラマのことなんか考慮してない
マウスオーバーで変数の型を確認できたり、縮小変換に警告を出してくれたりする程度のありふれた機能が、ありえないぐらい賢いとな
お前さんはメモ帳でコーディングしてるのか
>>220
emacs にもそんな機能がほしいと思うことがあります システムハンガリアンでミスを減らせるなんて事はない
むしろ害悪
>>221
俺のemacsには搭載されてるんだが
環境構築もプログラマの腕のうちだからな >>221
有るよ。
irony-eldoc や company-mode を入れろよ。
Emacs こそ最強の IDE だろうが。 今時システムハンガリアンを使うやつはあり得ないくらいのバカだということが決定しました
>>218
間違ったコードは間違ったように見えるようにする、について、
あなたが指し示した引用元が言及してるのはアプリケーションハンガリアンについてなんだけど…
システムハンガリアンについては否定的意見。
ちゃんと読んだの? >>218
APIの仮引数にシステムハンガリアンをつけたことで、間違ったAPI呼び出しが間違ったように見えるのはいつ?
APIのリファレンスなり宣言文なりを自分のコードと見比べたときでしょ?その時必ず型情報も見てるよね?情報重複してるよ?
あとIDEが自動でミスを排除してくれるなんて書いてないよ?ちゃんと読んで 入れる変数の型と引数の型を確認しない奴とかいるのか
暗黙の型変換は警告を出せばいいし
どうしても見落とすのならコンパイルエラーにしてしまえばいい
あとメンバ変数もテキストの色を変えればいいからm_もいらない
m_だけならまだ我慢できるけど
this->を必ず付けるルールと併用するのは本当にやめろどっちかにしろ
> this->を必ず付けるルール
破門だろ
C++使うなそんなボケどもは
ちげえんだよなぁ
thisというキーワードが存在してるから、その存在そのものが、それを書かねばならないような強制力を産み出してる
「存在するが、書かなくてもいい」っていうどっちつかずが、一番論争になる
その反対が「存在しないから書けない」だ
これだと単純明快だ
なんせ、書けない
「書くべきか書かざるべきか」のどーーーでもいい二択に迫られると、とたんに宗教になる
キーワードが存在するのと実体が存在することの違いがそんなに大事なのか?
じゃあvtableのキーワードが存在しないことを、おまえはどう考えている?
おれがそのソースを引き継いだらまず初めにやることは一つ
「this->」から「」への全ソース一括置換
「m_」はダメで「_」ならいいってのはなんというか、合理的な理由よりも感覚・感情的なものかね。
this-> つけるほうが分かりやすくていいと思うのですが、変てこな接尾辞・接頭辞よりも
m_xxx も xxx_ もなんの保証にもならんからな
this->は必ずメンバになるけど
余計な命名規約を作るくらいなら言語機能を使った方が良いわな
this->派だわ
thisで明示した方が所在がハッキリして良いナリ
当職は名前空間もusingせずに明示しろ派ナリ
安易な省略はタイプ数を減らすという軽微なメリットと引き換えに可読性を落としケアレスミスを誘発するという恐ろしいデメリットを孕むナリ
>>237
「m_」はいらないな
↓
ローカル変数とかと名前が被ってめんどくさい
↓
キャメルケースにはしたくない
↓
「_」だけ残る 245デフォルトの名無しさん2018/02/19(月) 00:18:14.94
C/C++なら必然的に末尾に付けるしかない
先頭に_付けるような情弱は死ねばいい
Perl/Pythonだと先頭に付けるけどな
やらんけど、前一つなら規約には引っかからないんじゃなかったけ
未定義なのは
_始まりでグローバルスコープにあるもの
_始まりでアルファベットの大文字が続くもの全て
__で始まるもの全て
1番目の_始まりなだけならローカル変数、引数、メンバでは予約されていないので使ってもよい
>>238
名前に変なルールを導入するか this を付けるかの二択であれば this の方がマシというのはわかる。
わかるが、必ずつけるルールにしちゃうとかなりウザいわって話。 >>242
わかるんだが、そういうルールってすぐに教条主義に陥るからうんざりする。
技巧として使う using にまでグダグダ言うやつが絶対に出てくる。 コーディング規約はうろ覚えだけど自由度の高いBoostスタイルを薦める
publicな識別子はstdに合わせて小文字スネークケース
マクロはBOOST_から始める
インデントはスペース、一行の文字数は80文字を推奨
意味のある名前を付けることを推奨
ファイル構成に関するもの
その他細々としたもの
ライブラリごとのローカルルールがある場合もある
あとは自由
thisを付けろだとか改行の仕方だとかは一切書かれてない
>>248-249
お互いにマナーを守る世界は過ごしやすいがマナーの厳守を要求し出すと途端に息苦しくなるナリ
自分にも他人にも読み易いコードを書こうという気遣いが見て取れるなら細かく突っ込んだりはしないナリ this->で必ずメンバというやつら
じゃあ必ずブロック内変数という表記もしたらどうだ
使うライブラリや開発環境の内部のスタイルに合わせるけどな。
派生クラスとかAPIのラッパークラスとか作り始めると、
どうしても内部の書き方に合わせておいた方が読みやすいし。
今でもWin32とかMFCでやることもあるけど、
そのときはm_とかpとかhとかdwとかバンバンつける。
使う側の都合に合わせろよ。 ラップしてるのに中身のスタイルが漏れてるんじゃラップの甲斐がなくね?
中身を知ってる人がちょっとした便利のためだけに薄いラッパを作る場合ならそういう選択もあるだろうけど。
コンバータにあわせろよ。C#で作ってコンバータかけた方が綺麗スッキリするんだから。
>>253
そりゃAPIに渡す構造体でdwSizeとか使われてたらそこだけは合わせざるを得ないけど自分のコードスタイルを合わせる必要はないだろ Windows メインで作業されている方で、
valgrind を併用している方はおられませんか?
もしよろしければ使用感をお聞かせいただけませんか
operator new()/operator delete() 乗っ取りデバッグに限界を感じてしまっている状況です
(cl や bcc32/bcc32c/bcc64 では new/delete 乗っ取りができません)
いや、さっさと入れればいいのですが、仮想環境とかよくわからないし…Vine Linux 以来触ってないし…
windowsならapplication verifier使えば?
すみません、BOOST_TTI_HAS_MEMBER_FUNCTIONを使って短くする以前に元々が間違っていました。
以下の3つでオーバーロードしたかったのでした。
・funcというメンバ関数を持つダブルポインタ
・funcというメンバ関数を持たないダブルポインタ
・それ以外
それで思ったのですが多分、Boost.TTIライブラリで
〇〇というメンバ関数を持つクラス、を識別するメタ関数は作れても
〇〇というメンバ関数を持つクラスのダブルポインタ、は無理な気がしてきました。
一旦諦めようと思います。
>>263
あと2年待てばconceptできるかもよ (VBみたいな名前付き引数が実現されたら
システムハンガリアン否定論者をぎゃふんと言わせられるのに…
システムハンガリアン発祥の会社が何か作ったら否定論者がぎゃふんと言うのか?
おまえの頭の中は論点先取だか循環論法だかがグルグル回っているようだな
↑
想像してごらん全ての人々が
dwRet = ::WaitForSingleObject( hHandle = m_hThread, dwMillisecond = m_hTCTmo )
と書く世界を、
ごめ
誤: m_hTCTmo
正: m_dwTCTmo
見れば間違いがワカルのがハンガリアンの極めて良いところ
一分間で間違いに気づいてはいるものの
そもそもの書く瞬間にはどうやら人智を用いても気付けないらしいから
IDEにエラー出してもらった方が早いんじゃあねえの
実は人間の集中力を超えたところにある方法論で、実践するとストレスが溜まるっぽいから、機械任せにした方がいい
それに、書いてる最中は変数の型まで考えたくない
見て分かることは、機械任せにすれば見なくても分かるから、
今のご時世、人間の有限の集中力を目視チェックなんかに使いたくない
脳みそのリソースはもっと別のところに使うべきだ
つまりは、書いてる最中は脳みそが「それが正しい」と思い込んでるから、
間違いは自分自身では絶対に分からない
これがバグを作り込む
hだったかdwだったかを脳が自動的に混同してるから、その分だけ余計に脳のリソースを使っている
「なんで書いている最中に自分自身で気付かないのか」、これ、とても重要だよ
変数名と型が一致してるという保証がゼロだからシステムハンガリアンなんて無駄以外の何物でもない
無駄というか悪
>>272
俺のレスもプログラムも表現と意図が一致してるという保証がゼロ、
まで読んだ その場合、やめられる方だけやめればいいな
つまりハンガリアンを。
>>272
そういう事言い出すと「関数名と機能が一致してる保証がゼロ」や「クラスメンバの隠蔽が完璧である保証がゼロ」などといくらでも難癖を付けれるナリ
ヒューマンエラーを理由に不要と結論付けるのならあらゆるコーディング規約が不要という結論になってしまう、これはいけない
命名規則は可読性の向上に結びつくものでなければならない、規約を違反する事で起きるトラブルはプログラマ側の責任、それは分かるよね? ヒューマンエラーが起きる部分は極力排除して機械任せにできる部分は機械任せにすればいい
ハンガリアンを導入する理由はもはや無いな。可読性悪いし。
>>278
いや、ハンガリアンは可読性はよくなる方だよ
整合性維持に難があるだけで 可読性ぐらいテンプレートによる高度なメタプログラミングに慣れた諸兄なら
ハンガリアンごとき目を慣らして解決できるはずなんじゃ…
>>276 >>282
両者は共存不可能な対立概念ではないけどね。
細かいことを言わせてもらえば、
「ハンガリアンとポリッシュ」か「ハンガリーとポーランド」と
並べてくれた方が座りがいい気もするけど…。
「ハンガリアン記法とポーランド記法」だとあまり気にならない不思議。 >>266
名前付き引数イディオムとenable_if<is_same<...>::value>が最強と言うことだな
※プログラマが、使用者が型を間違えないようにと気を使うのが正しいなら、間違えたらコンパイルエラーになるこれが最強だろ? >>277
ちげえんだよんぁ
可読性じゃねえんだよ
>>268を見てみろよ、
読む時じゃなくて書く時のヒューマンエラーだ
なんで入り込んだのか全く分からんようなミステイクだ
プログラミングが工業的生産の一種なら、その手のヒューマンエラーは無い方がいい
で、改めて>>268を見てみると、「可読性」があってプレフィクスの間違いに気付いてはいるものの、
そもそも書く段でなんで間違えたのか、それが全く分からない
他人はおろか本人すらも自覚できない謎の理由でプレフィクスを間違えてる(これがヒューマンエラーなんだけどな)
なんで、後だしジャンケンだと、「プレフィクスが最初から無ければ、間違いも発生しえなかった」、とも言える
もしかすると、書く時に間違える/読む時に間違える の比率を考えると、ハンガリアン記法は書く時に間違えやすいが読むときに間違いにくい……のトレードオフなだけかもしれん
要するに、可読性と生産性のトレードオフだけなんじゃあねえのか?
それに、読む時のヒューマンエラーと書く時のヒューマンエラーをわざと混同してるのはいただけない void func(int a)
{
//aが何型かわからない
//アホかおまえは
}
template <typename T>
void func(T lpszA)
{
//lpszって書いてあるからTはLPSTR型だな
//アホかおまえは
}
>>288
func()が常に1画面に収まって1万行の関数とかでありえないという根拠は
>>289
テンプレート定義時の引数に対して引数内容固有の命名が難しいのは
ハンガリアンに限ったことではないからハンガリアンに対する批判になんね
テンプレート批判論者には考える力がないのかね… ごめ
×:テンプレート批判論者
○:ハンガリアン批判論者
テンプレートに対してはハンガリアンは全くの無力だよなあ
一貫性の観点からやっぱりハンガリアンは無い方がいいわ
.>>290のレスを見てテンプレートの実体化時までハンガリアンが無力なことにされてはかないませんなあ… そもそも関数が長い場合は型情報を持たすのもありだよな
システムハンガリアンをやめさせようとして先に関数を短くしなきゃだめだなと追う結論に至って放置した
//1万行の最長不倒関数を書く
//アホかおまえは
void func(int lpszA)
{
//lpszって書いてあるからLPSTR型だな
//アホかおまえは
}
>>295
「1画面に収まらない」を都合よく無視しないように システムハンガリアンはDWORDをintに型名変更するだけでその変数名全部終わるからなしかも一瞬で
300デフォルトの名無しさん2018/02/25(日) 23:57:37.89
>>299
dwをiに置換するだけだからリファクタリングが楽っていう意味? まったく逆だ
dwからiに全部置換していかないと変数名の意味を為さなくなるからシステムハンガリアンは愚かさ甚だしいと云うておる
アンパンマン調で例えるなら型名変えるだけでメンテ百倍みたいな
組み込み型はいいけどクラスはどうすんのさ
意味の分からないサフィックスを付けられても困るぞ
ハンガリアン!新しい型だよ!
有難う!デザパタ娘ちゃん!
メンテ百倍!ハンガリアン!
そもそもDWORDをintに変えることが滅多にない
dwとか書かれてもDWORDの定義を知らないと意味不明だし
やるなら符号の有無とサイズが分かるように書かないと意味ないでしょ
>>298
おまえは間違いなく1万行と書いた
その史実を誤魔化すことはできない
「ありえないという根拠は」という問いを反論として用いるのは
俺が「ありえない」と言った(事実と違うが)ことが
おまえが「ありうる」と思っているのと違ったからだろう
いずれにせよ「アホかおまえは」にふさわしいハチャメチャだな 309デフォルトの名無しさん2018/02/26(月) 08:09:57.39
>>308
俺も使う
ただし名前そのものをポインタっぽくするだけで
ハンガリアンのプリフィックスとしてではない ハード直叩きのドライバ屋はデータバスやレジスタの幅を間違えると大変だから
物理層の実装ではハンガリアン使うこともあるよ
>>313
むしろそれはアプリケーションハンガリアンじゃね? 間違えると大変だからハンガリアンを使ってはならないんだよ
偽の情報に頼るんではなくて元を逐一確かめないと
今勉強してるんだけどC++ではポインタを使わずに参照で書くのがデフォルトなの?
>>315
不一致が存在しない事が保証されてれば問題無いんやな
そういう事ならつまり変数宣言とプレフィックスが全て一致してるかチェックするスクリプトとかがあれば満足って事でええんか? >>316
ポインタも必要に応じて使うけど、メモリ管理の煩雑さとミスの危険性を避けるために参照やスマートポインタやコンテナ、イテレータなど他に適切な物がある時はなるべくそちらを使うのが流儀かな。 >>316
デフォ・・・まあ、そう言えなくもないか
参照でもポインタでもどっちでもいい用途には参照
ポインタでしかできないことはNULLに++や絶対番地指定
参照でしかできないことは一時オブジェクトやコピコン類 書き込むときは参照ではなくポインタにしろと言ってた人がいた。
理由を聞いたら「なんか書き込んでる感がない」だった。
グーグル規約だと書き込む引数は参照ではなくポインタにしろってなってる
でも標準ライブラリが普通に参照で書き込んでるので意味ないかなと思う
好きな方使えとしか言いようがない
ただ参照はnullポインタが無いという特性はある
>>322
自分もその人の気持ちは理解できた。
func(a, &b);
と書かれていると、bに結果を書き込んでいる感があるし。 レスサンクス
cからだからポインタで書いちゃいそうだわ
ローカルで宣言したunique_ptrを他のメソッドに渡してデータをつめたいばあいってどういう引数で渡せば良いの?
unique_ptr<Hoge> ptr(new Hoge);
hogehoge(ptr);
Hogehoge::hoge(const unique_ptr<Hoge>& ptr){
ptr->aaa = 123;
}
これでいける?
なんかウェブサイトみてると&&二つとかあったりするの見かけて混乱してきた
&&は所有権ごとぶん投げる時に使う
渡した後も呼び出し元で使うんだったらそれて合ってるぞ
>>327
それだったらunique_ptrじゃなくて参照渡せば良いだけじゃ 知らない間に、&& みたいな参照渡しもできた
Rust の所有権ムーブの事
所有権を渡すのってstd:move()だと思ってたんだけどconst &&でもいけるの??
C++17でstd::iteratorが非推奨ってなっているみたいだけど代わりに何使うの?
>>332
std::move は rvalue にキャストするだけで、それ自体にはムーブする機能はない。
実際にムーブの処理をするのはムーブコンストラクタやムーブ代入演算子の方やで。 && は単純に右辺参照って意味しかないから、 rvalue を受け取れるってだけ。
だけど lvalue でもムーブしてぇってときは std::move で rvalue にキャストすんの。
右辺値参照とか難しいなー
最近ようやくC++11使えるようになったから全然いってることがわからん
右辺値参照が使えなかった頃は、std::swapでスピード最適化していた。ポインタとメモリー確保を含む構造体は、
単純にスワップしたり、単純にバイト単位コピーしたりするのはまずいことがある。
そういうときに、std::swapを使う。右辺値参照は、それよりちょっと速くて賢いが、テンプレート型を理解してないと多分理解できないと思われる。
右辺値参照の型はテンプレートを使った特殊な型だと考えるのが自然。
T&& === rvalue_ref<T>.
std::move(T&)はrvalue_ref<T>という型。
訂正。
std::move(T&)の戻り値はrvalue_ref<T>という型。
すみません、テキトーなことを書いたので、銃殺されます。
実際のところヘッダファイルから std::move の定義を抜き出すとこんな感じ。
template<typename _Tp>
constexpr typename std::remove_reference<_Tp>::type&&
move(_Tp&& __t) noexcept {
return static_cast<typename std::remove_reference<_Tp>::type&&>(__t);
}
テンプレートの都合で面倒くさくなってるけど、実態としては static_cast してるだけ。
そのstd::remove_reference<T>::typeはTから左辺値参照や右辺値参照をはずした型になるね。それに&&を付けるんだから、左辺値参照が右辺値参照になる。
やはり、constexprやnoexceptを付けた方が性能がいいんだな。
C++17 では noexcept は型の一部という扱いに変更された。
例外を投げないなら投げないと書いておかないと他のライブラリとの組合せで型エラーになったりすることもあるかもしれんぞ。
江添本にこの辺りのチートシートと問題集いれたら100部くらい売り上げ増えるのでは
江添ってあれか。ニートの時にやることないからたまたま目についたC++の仕様書を読み込んでたら
いつの間にかすごく強くなったという、ホリランみたいな。
おまえそれをバカにできるのか?
仕事ってそういうもんだぜ
目の前の案件のために必死こいても付け焼き刃にできることは知れてるんだよ
「ヒマ」なときに遠くを見て投機的にコツコツ努力したことが
あとで花咲くことがあるし咲かないこともある
賭に勝った者を、降りたやつがバカにできるのか? え、おい
>>320
>>322
書き込むときポインタ渡しにするのは
C++には参照渡しがin/out/refのどの意味なのか表すシンタックスが現状無いから
というのが主要な動機だと思うが
inならconst T& aというのは比較的読み筋だが
T* pと書いただけだとoutなのかrefなのかやっぱりわからん… && は、Rust のmove の事。
所有権移転。移転元が空になる
基本的に数年は、ドワンゴ江添と共に、山ごもり!
江添が空海なら、漏れは最澄w
悟りを開くまで、空海・最澄の一問一答が、延々と続くw
rvalue reference 自体はムーブしねぇつってるだろ。
&&参照は「このオブジェクトもういらないからぶっ壊してもいいよ」というサイン
言うなれば肉屋へ行く馬車
野生のオブジェクトは誰に断る必要もないので勝手に連れてかれて解体される
家畜を渡す時は解体に同意するサイン(std::move())が必要
Fooクラスのunique_ptrがつまったvectorを作って、他クラスのメンバ変数にセットするときはどう渡すべき?
作った元ではもう使わないから所有権放棄していいとする
const参照渡しにして、渡された側でvectorの中身を全部std:move()して新しいvectorにつめるのが一番最初に思い浮かんだ
そんなことしなくても最近ここででてる、&&つけて渡してそのままセットすれば解決するのかな?
vectorを丸ごとmove付けてコンストラクタに渡せばいいよ
出来上がった後で渡したいならswapすればいい
なるほどー
コードにするとこんな感じかな?
std::vector<std::unique_ptr>vec_hoge;
...
Hoge hoge;
hoge.setHoge(std:move(vec_hoge))
Hoge::setHoge(vector<unique_ptr>&& vec_hoge) {
this-> vec_hoge = vec_hoge;
}
せやな。
rvalue reference は lvalue だぞ。
noexceptにtrue,falseがある理由については
#include <type_traits>
template<typename T>
void test(T t)noexcept(is_unsigned<T>){
//Tの型がunsignedの時だけは例外は投げない
}
こういう事が出来ると書いてあったけど、c++17以降も問題なく使えるだろうか?
is_unsigned_vだろ
なぜC++17以後で廃止になると思ったんだ?
stdも抜けてた。。。
廃止になるじゃなく面倒な事になりそうだと。
unsigned は組み込み用だろ
0 〜 255 のカウンターなどで、無限にループする。
255の次に、0が来る
overflow にされると困る
>>368
組み込みでなくても極々普通に使うし、標準ライブラリ使ってれば知らぬ間に使ってる。 普段は uint_xxt と size_t しか使わんわ
int と ptr あんまり相互に変換しないし
>>373
こうなった
---- BEGIN BACKTRACE ----
1 : 0x00e76873 : Project1 : mycode::foo : c:\users\\source\repos\project1\project1\main.cpp(116) :
backtrace();
2 : 0x00e76513 : Project1 : mycode::bar : c:\users\\source\repos\project1\project1\main.cpp(120) :
foo();
3 : 0x00e76563 : Project1 : mycode::baz : c:\users\\source\repos\project1\project1\main.cpp(124) :
bar();
4 : 0x00e76b33 : Project1 : mycode::hoge : c:\users\\source\repos\project1\project1\main.cpp(128) :
baz();
5 : 0x00e76f0d : Project1 : main : c:\users\\source\repos\project1\project1\main.cpp(134) : try {
6 : 0x00e7870e : Project1 : invoke_main : f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(78) : ?
7 : 0x00e785b0 : Project1 : __scrt_common_main_seh : f:\dd\vctools\crt\vcstartup\src\startup\exe_common.inl(283) : ?
---- END BACKTRACE ---- >>375
プロジェクトの設定はdbghelp.libを追加しただけでしょうか?
あとWindows10ですか?7ですか?
>>376
自分もそれを読んでx86とx64両方試したのですがダメでした、、、 >>377
Windows10で実行
ライブラリは追加したのと
このFileNameがchar*でmsvcでは通らないから適当に文字列のバッファを作って渡した
>94 line.FileName = "?"; >>378
自分はWindows7&VisualStudio2017なのですが
dbghelp.lib、dgbhelp.hを探すと以下の場所にあるのでWin10でしか対応していないのかなと…
C:\Program Files (x86)\Windows Kits\10\Lib\10.0.16299.0\um\x86
C:\Program Files (x86)\Windows Kits\10\Include\10.0.16299.0\um
C:\Program Files (x86)\Windows Kitsの下には8.1と10
という名前のフォルダがあるのでOSの番号ぽいです。
dbghelp.dllならそこらじゅうにあるのでLoadModule関数で呼べばいけるのかも VisualStudio Installerで構成の変更をしようとすると
'Windows XP Support for C++'というのがあって
これがWindows7用のSDKらしいです。(どんな名前の付け方だ…)
これをインストールするとめでたくdbghelp.libとdbghelp.hが追加されるので
それでコンパイルしようとすると
#include <dbghelp.h>
とかくだけでコンパイルエラーになってしまいました。
エラー C2760 構文エラー: トークン '識別子' は予期されておらず、'型指定子' が予期されています scratch c:\program files (x86)\microsoft sdks\windows\v7.1a\include\objbase.h 239
Windows10を買うかVisualStudio2015をインストールするかしかないのかもしれません;;
コンパイラを作っているんですが、char 10bit short 18bitの時はsizeofはいくつを返せばいいんですか?
>>382
アドレス単位を返す。ワードアドレッシングなら通常全て1になる メモリ上のレイアウト次第
その18ビットを隙間だらけでchar8個分のメモリに置いてるなら8だし、
詰めて2個分で置いてるなら2
sizeof(char)は必ず1じゃなかったっけ?
386デフォルトの名無しさん2018/03/03(土) 12:49:02.99
sizeofが小数を返しちゃいけないって誰が決めたの?🙄
>>386
仕様。
C99 だと 7.17 に size_t は sizeof 演算子の結果の符号無し整数型って書いてある。
C++11 だと 5.3.3 に sizeof 演算子の返却値の型は size_t って書いてあって、
18.2 に size_t は符号無し整数型って書いてある。 sizeof(bool) == 0.125 であって欲しいのかw
どうせ汎整数昇格で int になることばかりなので、
アドレス単位以下の小さなオブジェクトにする意味なんてないよ。
大きな配列で扱いたいときは std::bitset が有るし。
390デフォルトの名無しさん2018/03/03(土) 14:56:24.32
>>389
もしsizeofが小数を返したら汎整数昇格は適用されないんじゃない? この板に書いてあることがほとんどわかっていないようなクソ素人ですみませんがちょっとお聞きしたいことがあります。
Windows 7でOpenCVをTDM-GCCにて動かしたいと思っているのですが、どなたかこの設定で動かされている方など居られますでしょうか?
もしくは素直にVisualStudioなど使ったほうが良いのでしょうか?
昨日からあれこれ試しているのですがまったく動かないです。
>>393
俺ならパッケージマネージャがあるMSYS2+MinGW使うよ。
パッケージマネージャがないTDM-GCCなら、まず、OpenCVをビルドして、リンクできるようにしないといけない。
まあ、めんどうくさい訳で。 初心者はVSやるとよろし。NuGetというパッケージマネージャがあるよ。
片山様
レスありがとうございます。
そうですね、VSは重いという理由で避けていましたがやはりまずはちゃんと王道からやっていこうと思います。
慣れたらソースからビルドもしてみたいですが、まずはOpenCVであれこれしたいのでやりやすい環境で頑張りたいと思います。
ありがとうございました。
VS の統合開発環境を外したツールセットだけの SDK もあったはず。
でもまあ初心者は統合開発環境があった方がいいってのは同意だな。
C++の文字列、u16やu32stringとか乱立してるけど今時TCHARとか使わないでしょうか?
string,wstring,u16string,u32string...どれか決め打ち?
主に使ってるライブラリ/フレームワークに合わせれば?
何でもいいなら multibyte で utf-8 一択だろう
ucs2 (16bit) にしても ucs4 (32bit) にしてもどうせ
合字とかで1コードポイント1文字にならないから意味ないし
コンテナは string でも何でも好きなものを
どうやろな?
Windows だと API が UTF-16 前提だからそれで揃えるってのは悪くない選択だと思うし。
>>398
TCHARはcharとwchar_tをvisual studioのプロジェクトの設定で切り替えてtypedefしてる型だ
マイクロソフトのライブラリの一部
u16stringとu32stringはstd::basic_string<char16_t>とstd::basic_string<char32_t>のエイリアス
UTF-16とUTF-32の文字列を扱うクラスで標準ライブラリの一部
そもそもどっちかというものではない
std::basic_string<TCHAR>とか使ってもいい OpenCVのビルドぐらいCMakeでGUIでできる
>std::basic_string<TCHAR>とか使ってもいい
ほんとそれ
ていうかWin32APIでサポートされるうちはやっぱマルチバイトが無難
ShiftJisなんて廃止して、UTF8に統一してしまえば良かったよね
UTFはソートのコストが高いから痛し痒しだけどね
SJISはその点は優秀かと
文字コードを統一したところでロケールの切替えはどうせ必要なわけだし、
内部的な処理が UNICODE に統一されたので良しとするしかなかろ。
utf8に統一したら、ロケールの切替って表示する文字列の言語を決める位の意味しか無いのではないかな
異なる言語の文字列でもそのまま字化けせずに表示出来た方が都合が良いように思うけど
Windows はもう 20 年以上前から Unicode 化はやってるんだってば。
UNICODE 版の API を正しく使う限り文字化けしない。
フォントの設定とかで化けることはあるかもしれんけど、
それも今はフォントリンクとかでおおよそ上手いこと処理してまうしな。
UNICODE 化できていない今までに作られたカスなアプリが消し去れないし、
カスなアプリのために ANSI 版の API (の挙動を制御するためのコードページの切替えの仕組み)
は残しておかなきゃならないけど、
Unicode への統一そのものは出来てるから満足するしかない。
っていう話ね。
だったらVisualStudioで作ったソースファイルのデフォルトがShiftJIS固定なのをそろそろなんとかしてくれよ
LinuxとかのシステムコールもUnicode化されたら考えるわアデューノシ
だいたいwchar_tとかcharの倍容量を食うじゃん?
2が3になるとかならまだしも1が2になるというのは精神的にインパクトがデカイ
L"Hello World!"のバイナリをダンプしてみたらトラウマを抱え込むレヴェル
というのもあるし他環境とのソースコード共通化も視野に入れる場合やっぱマルチバイトしか…
WindowsのUNICODE版APIはUTF-8と相性が悪いからクソ
せやろか?
内部表現として使う文には UTF-16 って良いと思うけどな。
UTF-8 との間なら変換コストも大したことないし。
>>416
iOS / macOS / Windows / Java と多くのプラットフォームの
API で文字列としてUTF-16 が使われてるから割と使うけど、
近年多用される絵文字とかが全然1文字1符号にならんので
ロジックを基準する上ではUTF-8より便利ってわけでもない。
文字列の処理を描くときは合字以外は1文字1符号になるUCS4 の方が良い。 なぜ世界中の頭脳を集結させても完璧な文字コードは作れないのか
x86アーキテクチャーがRISC-Vに置き換わったら考えるわノシ
ていうかコルモゴロフ複雑性が計算可能関数だったら考えるわノシ
韓国がUNICODEにすごい文字数予約済みにしてあるとか聞いたことある
>>417
どうせイテレータでアクセスするから、合字はどうしようもないにしても
先頭からコードポイント単位で読む分にはどの符号化を使っててもあんまり変わらん気がするが。 >>423
UTF-16 だとサロゲートペアが出てくるからマルチバイトがマルチワードになるだけ
ucs4 だとそれが要らなくて符合とコードポイントが1:1対応になるんだよ。
何年か前まではサロゲートペア?なにそれおいしいの?でも済んでたけど
今の時代それは無理だし 要は
utf-8、utf-16 → 1符合 ≠ 1コードポイント ≠ 1文字
ucs4 → 1符合 = 1コードポイント ≠ 1文字
だから完全自作の文字列処理ではucs4が楽だよという意見でした
テキストなんてたいしてメモリ食わないしね
おしまい
charset_cast<utf_8>()みたいなの欲しい
おっと、 u16string のイテレータはサロゲートペアは解決してくれないのか。
まあそれも小さなラッパを作ればどうとでもなる。
UTF16でサロゲートでガチャガチャやるくらいならUTF8でちゃんとやった方が実り多いし
そんなんやりたくないならUTF32使えばいいし
中途半端だよねUTF16
どこかでみたけど歴史的にはutf32やutf16よりutf8が新しいんだろ?
オリジナルのXEROXのコードへの先祖返りではないかな?
visualstudio2017でBoost.Testを試したいのですがうまく行きません。
Nugetでboost-vc141をインストールしてテストプロジェクトをWindowsコンソールアプリケーションとして
追加し、Helloworld的なテストプログラムを書きました。
ビルドは通るのですが、テストエクスプローラーにテストが認識されません。
#include "stdafx.h"
#define BOOST_TEST_MODULE MyTest
#include <boost/test/included/unit_test.hpp>
BOOST_AUTO_TEST_CASE(my_boost_test) {
const int x = 1;
BOOST_CHECK(x == 1);
BOOST_CHECK(x != 1);
}
VisualStudio2017のバージョンは15.5.7で
「Boost.Testのテスト アダプター」はデフォルトでインストールされるようになっていたので
インストールされています。
標準ライブラリを前方宣言にすることに意味ってありますか?
newした配列がいつの間にか解放されてて、
プログラムの最後でdeleteすると必ずアクセスエラーで落ちるんですが、
newは勝手に解放されることあるんですか?
>>436 どっかで未定義動作に堕ちてるならそんな結果になることもあるだろね。 ・どっかでメモリの取り扱い間違えてnewの管理情報を踏んづけて壊してる
・unique_ptrやshared_ptr、その他スマートポインタ的なものに理解せずに渡してる
多分このどっちか
>>436
「解放されてて」というのは、どうやって確認した?
たとえば要素のデストラクタが実行されているとか、
別件で確保するメモリに再使用されているとか、
そういうことが起きているのか? >>436
constructor
destructor
copy constructor
operator=()
のいずれかに誤りがあるのでは?
概念コードを書いてみなさい >>436
operator new()
operator delete()
を捕捉するのもいいかもね、根本的に見直す時期だと思う ファイル分割をしてみたく、プログラムをヘッダファイルとcppファイルに分割しようと挑戦したのですがよくわからないエラーが出まくります・・
プログラム超初心者なので凄い初歩的な部分を間違えているかもしれません・・・
エラーですが、ヘッダファイルの方で
'vector':'std'のメンバーではありません
'vector':定義されていない識別子です
'string':定義されていない識別子です
'cv': 識別子がクラス名でも名前空間名でもありません。
'Mat':定義されていない識別子です
'ofstream':'std'のメンバーではありません
'ofstream':定義されていない識別子です
みたいなエラーが出ます。
ヘッダファイルは、二重インクルードガードと関数のプロトタイプ宣言しかしていないのですが
上のようにそ、のプロトタイプ宣言の型とかに対してのエラーが出まくります
何かヘッダファイルに付けたほうがいいのでしょうか?
分かる方がいたら、教えていただけますでしょうか。
ちなみに、visual studio で作業していて、プロジェクトはコンソールアプリケーションで作っています。
もしかして、自分でmakefileとかを作る必要があるのでしょうか?
ヘッダーの方で
#include <vector>
などが足りないのでは。
ヘッダーは、自己完結にした方がいいらしい。
よく見たら、自分の参考にしていたページでヘッダファイルのincludeは最小限に抑えると書いていました…
てっきり、ヘッダファイルではincludeはしないものなのかと…
最小限というのは、エラーが回避できるstdio.hとかの最小限のファイルだけヘッダでincludeして、他のmath.hなどはcppファイルでincludeすればいい感じですか?
最小限というのは、コンパイル時間、ビルド時間を短縮するためだから、小さなプログラムでは気にする必要はない。
cppとhppで#includeを分けるというのはよくあることだ。
>>443 の書きぶりからして
自作のヘッダファイルに std::vector を使った関数のプロトタイプがある、
しかしヘッダファイルの先頭では <vector> を#includeしてない、て感じね。
これは >>444 と同じ話。
あと >>445 で <stdio.h> と書いてるところを見ると
参考にしてるページは少々古い情報かも。
「あえて<cstdio>でなく<stdio.h>をインクルードする」ことについて
何か理由があるのかも知れないけど。 449デフォルトの名無しさん2018/03/06(火) 17:54:41.92
Cソースのincludeの位置にヘッダファイルの中身を貼り付けたときにコンパイルできなきゃだめ
たぶんCソースの中で他のincludeよりも前に新しいヘッダファイルのincludeを書いてるんだろう
>>448
なるほど、cstdioの方が良いんですね
なんか二種類あるけど、どっちなんだろーと思ってたので、勉強なります
次からそちらを使います C++のリファレンスとかで[first,last)というふうに左右で括弧が違う表記があるんだけど、これはIteratorに関しての表記ですか?
>>452
数学方面の書き方を源流にしていると思います
[x, y) は x は含み、y は含めない半開区間を示しますが、それを類推したものでしょう >>452
範囲の数学的な書き方、半開区間とかなんとか
それだとfirst以上last未満の範囲、ということ >>453,454 数学でしたか!勉強になります。 mutex g_Mtx;
int g_Val = 0;
int Func( int A, int B )
{
int Val = A * B;
lock_guard<mutex> Lock( g_Mtx );
return g_Val = Val;
}
void ThreadFunc0()
{
int Val = Func( 2, 3 );
// Valを参照する処理
}
void ThreadFunc1()
{
lock_guard<mutex> Lock( g_Mtx );
// g_Valを参照する処理
}
上記のようなスレッド関数が非同期に実行されるとき、
Func()はスレッドセーフ(g_Val書き換え中に参照されない)でしょうか?
(1)lock_guard<mutex>によるミューテックスロック
(2)g_Valの書き換え
(3)戻り値を呼び出し元スレッドにコピー(あるいはムーブ)
(4)lock_guard<mutex>がスコープから外れアンロック
というシーケンスを期待しています。
endならともかくlastは区間内の最後の要素なんじゃ…
基本的な質問なのですが、以下のプログラムがエラーになるのはなぜでしょうか?
char* pc = "abc";
pc[0] = 'z';
cout << pc << endl;
以下のプログラムでは意図通りに動きます。
char ac[] = { 'a', 'b', 'c', '\0' };
cout << ac << endl;
ac[0] = 'z';
cout << ac << endl;
>>459
上は変数 pc はリテラル文字列の先頭を指すポインタ。
下の変数 ac は配列で、それを文字列 "abc" で初期化するって意味。
リテラルの破壊は未定義。
破壊しないことをあてにして破壊不可能なセクション (メモリ領域) に配置されたりすることもあるので、アクセスエラーが生じる。
あくまで未定義だから出来ちゃうこともあるし、コンパイラオプションで制御できたりもするけど、基本的にはあかんやつ。 >>458
仮引数名をendにすると関数名のendと紛らわしいからだよ
説明の文中にendが出てくる度毎にいちいち仮引数か関数か断るハメになる >>460
ありがとうございました。
Pythonでimmutableとかいうのがありますが、それでしょうか? すみません、また、ベーシックな質問です。
char* pc1 = 1; → エラー
char* pc2 = NULL; → OK
char* pc3 = 0; → OK
なぜ、2番目と3番目はOKなのでしょうか?
char* pc1 = 1;
がエラーになるのは、 int 型の値で char* 型の変数を初期化できないからだとすれば、
char* pc3 = 0;
もエラーになると考えることもできると思います。
>>462
Python なんか知らんがな。
Python の immutable は Python の immutable であって、それが C++ の何物かであったりはしないよ。
C++ のリテラルを破壊した結果は未定義というのは C++ のリテラルを破壊した結果は未定義という規則であるだけ。
似て感じられたとしても一対一に対応付くような単純なものではないので、
背景にあるメカニズムを理解せずに翻訳して理解しようとするような方法はお勧めできない。 >>464
なるほど、そういう規則だからリテラルを破壊しようとするとコンパイルエラーにするわけですね。
ありがとうございました。 >>465
書き忘れてたけど、 C++ の文字列リテラルの型は const char[] なので、
const 付きでないポインタに渡すと単純に型が合わなくてエラーになるはず。
C だと型に const が付いてないのに破壊するのは未定義ってことになっててあまりにもクソだったから改められた。 >>463
0 はポインタに型変換可能で、型変換した結果が空ポインタと等しいことが保証されてる特別な存在。
(ビットパターンが等しいとは限らないことには注意が必要。)
互換であることが保証されているので、処理系によっては
#define NULL 0
として定義していることもある。
余談だが、これはオーバーロードされた関数でうっかりしやすいので気を付けた方がいい。
たとえば関数 foo が以下のような型でオーバーロードされている場合、
void foo(int);
void foo(int*);
これを
foo(NULL)
と呼び出すと void foo(int) が呼び出されたりする。
今ではヌルポインタを表すキーワード nullptr が用意されたので、
NULL はあまり使わない方が良い。 >>466-467
ありがとうございました。
>>466
Visual Stuidoを使っていますが、以下でエラーは発生しませんでした。
char* pc = "abc";
cout << pc << endl; >>468
それはISO/IEC14882:1998の4.2で許されていたことに由来する
その後ISO/IEC14882:2011のC.1.1で廃止されたが
古いソースを通すために故意に違反状態のままにしている c++の規約に違反にしないためには一度変数に代入する必要があるという事?
オプションで指定できるんじゃね?
俺は GCC を使ってるから知らんけど。
違う
char const* cc;
cc = "abc"; //完全に合法
char* pc;
pc = cc; //不適格
pc = "abc"; //CとC++98では非推奨、C++11以後では不適格
pc = &"abc"[0]; //左辺値変形でこう解釈されていて
非constへのポインタに、constへのポインタを代入することになり、
暗黙のconst外しにあたるので、C++11が正論
pc = const_cast<char*>("abc"); //C++11以後ではこう書く
473デフォルトの名無しさん2018/03/07(水) 17:54:06.02
>>472
それもだめじゃね?
const領域に非constでアクセスするなんて罪深いことなんだから、ちゃんと別領域にコピーしてから扱わないと。 >>459
>char* pc = "abc";
文字列リテラルは不変だから、const を付けないといけない
古いライブラリで、const を付けていないものを動作させるために(互換性)、
例外的に使う場合だけに許される
>>463
>char* pc3 = 0; → OK
この0 は、数値型の0じゃない。
予約語を増やすのが嫌だから、= 0 と書いたら、特別な意味に解釈する。
分かりにくい、クソ仕様
virtual func( ) = 0;
これも、そう。
純粋仮想関数という特別な意味を表す >>473
書き込まなければ問題は無い。
が、 const 外しが必要な状態ってのが良くないことは確か。 >>474
いいや数値型の0だ
翻訳時に0と確定できる汎整数型の定数に限り
ポインタに暗黙変換できるという特例になっている
純粋仮想関数と関連付ける条項はない 純粋仮想関数と関連付けてはいないだろう
それはともかくとして
char * p = 7-7; // no error
class T {
virtual void f() = 7-7; // error
};
となる気がするので言ってることは合ってるか
C言語でNULLが0をdefineしたものだったというだけだろ
>>477
7-7は定数式なので0と完全に等価
純粋仮想関数の = 0 はA.8のpure-specifierで=0という特定のスペルと規定されているので7-7がエラーになるのは当然 いや疑問も呈していないし否定しているわけでもないのに当然と言われてもな…
>>479
それはあかん。
ひょっとしたら古い処理系でやってるのはあるかもしれんが、
規格違反のはず。 >>483
と、思って調べてたんだけど、 C++ だと確実にあかんようだけど C だとアリなのかもしれない。 おっ、こんな基本的なことで変更が入ってたのか。
でも当然といえば当然の処置よな。
>>484
しっかりして
流石にこの件では C と C++ 混同されたら対話が成り立たないよ C++の勉強+機械学習も勉強しようとVisual Studio 2017でtiny-dnnを用いたいのですが、tiny-dnn内でコンパイルエラーが発生します。
具体的にはxcontainer.hpp内でC3203というエラーが頻発したり、feedfoward_layer.hppではC2760というエラーが発生したりしています。
環境はWindows 7でVisual Studio 2017 communityです。
プロジェクトはwindowsデスクトップアプリケーションを用いています。
tiny-dnnのインクルードはプロパティのインクルードディレクトリに追加しています。
どなたか心当たりのある方がいらっしゃれば教えていただけると嬉しいです。
linux windows両対応のコードを考えている最中の質問です
unsigned int型の変数xの32bitに、char型の配列y[4]の8bit×4を当て込みたいです
y[0]から順にxの先頭ビットに入れたいのだけど
そういう時はどのようなコードになるのでしょうか
符号の問題で単純に24bitシフト+16bitシフト...みたいなことをすると期待の値にならないときが存在してます
>>491
シフトする前にunsigned charにキャストする ヘッダーファイルの関数定義から関数ポインタをtypedefする事は可能ですか?
C++98辺りのコンパイラです。
>>496
昔の C++ には decltype が無いもんな。
出来ないと思うよ。 出来ませんか。ありがとう。
再定義が面倒だったので楽したいだけだったんですけどね。
>>498
その手があったか。
でも C++98 で自動で推論させようとするとヘルパー関数を使う必要があるじゃろ。
意味のないオブジェクト生成 (最適化で消えるかもしれんけど) がださい感じはするよね。 >>496
たくさんあるなら
> ヘッダーファイルの関数定義から関数ポインタをtypedefする
コードを生成するツールを作るとか 502デフォルトの名無しさん2018/03/09(金) 22:17:46.30
>>496
マクロ駆使すれば
TYPEDEF_FUNC_DECL(なんちゃら);
FUNC_DEF(かんちゃら)
{
return;
}
みたいな書き方できないのかな?
なんちゃらは識別名と戻り値と引数
かんちゃらは識別名を指定するイメージ >>491
unsigned int x;
char y[4];
.
.
.
memcpy(&x, y, 4); >>491
xの先頭ビットとはMSBなのかLSBなのか メモリ上でのレイアウトとかもあるのでuint8_t経由でのシフトがいい
クロックが(メモリアクセスが問題にならない程)低くてシフトが遅いマイクロプロセッサは別
506デフォルトの名無しさん2018/03/10(土) 04:49:25.72
>>503
x = ntohl(x);
も忘れずに >>506
それが必要になるかどうかは場合による。 ネットワークバイトオーダーがここで関係あるのだろうか?
510デフォルトの名無しさん2018/03/10(土) 19:22:25.29
>unsigned int型の変数xの32bitに、char型の配列y[4]の8bit×4を当て込みたいです
>y[0]から順に
っていう要件だから、ホストバイトオーダーがビッグエンディアンかリトルエンディアンか分からない以上は常にntohlを付けるべき
511デフォルトの名無しさん2018/03/10(土) 19:24:15.74
char y[4] = { 0x12, 0x34, 0x56, 0x78 };
unsignd in x = 0x12345678;
これを等価にしたいという意味だろうから。
独習c++終わりそうなんだが次によむべき本とかある?
ありがとうございます
ひとまず>>513の本にしてみます そういえば最新版のEffective STLみたいな本って無いのか?
あると思うが訳者がへたくそで右辺値左辺値あたり意味ワカランかったぞ
その辺りの参考にするなら下手な日本語文献探るよりか英文そのまま読んだ方がいい希ガス
なんでもかんでも日本語訳してあるとほんと意味ワカランから
unsigned int x;
char y[4];
.
.
.
x = ((y[0] & 0xff) << 24) | ((y[1] & 0xff) << 16) | ((y[2] & 0xff) << 8) | (y[3] & 0xff);
Scott Meyers
Effective C++ 第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTI)、2014
Effective Modern C++ ―C++11/14プログラムを進化させる42項目、2015
Effective C++ は、昔の本のリバイバルかな?
内容が新しいかどうかまでは、分からないけど
テンプレートを使ったメタプログラムの有用性が分からん。コンパイル時処理で定数の階乗を計算してるけど実行時に値を変えれないなら、答えをベタ書きすればいいだけでは?
その値をベタ書きする手間をコンパイラにまかせることが出来るのが利点だと思うよ。
3の階乗を、tmpするより6とタイプした方が早いだろ
>>526
3ならいいけど10の階乗は?15の階乗は?21の階乗は?
それは整数型で表現できるか?
それは何桁になるのか?
適切な型をどうやって選ぶのか?
その値を静的な配列のサイズにしたいが数値を変えるたびに電卓で計算はしたくない
ならばfactorial<N>::valueと表現できれば便利ではないか
ということ その3という数値が別のファイルの特定の値に依存してる場合もあるし
意地悪するのはこの辺にしておいて
それはメタプログラミングでこいういうこともできるよ程度のものにすぎない
テンプレートメタプログラミングとはテンプレートを使ってソースコードを生成することだ
ソースコードを作るためのプログラミングだと思ってくれてかまわない
一般的な目的としてはジェネリックプログラミングを実現するために使われる
標準ライブラリではvectorからchoronoやtupleまでテンプレートメタプログラミングありきの設計になっている
値が小さいうちはそうかもしれんが16の階乗とか値が大きくなってもベタ書きが良い?
ちなみにconstexprが使えるc++11以降の話と考えてOK?
階乗の例はいい例とは言えんな
TMPで操作したいのはメインは型の方だからな
値も出来るよって例が階乗なだけで
>>529
> ソースコードを作るためのプログラミングだと思ってくれてかまわない
そこまでやるならPL/Iみたいに%FOR %SELECTみたいな普通の制御構文で書ける方がいいわ そんな貴方にtemplate+constexpr(c++14以降)
>>532
頑張って古代人用のコンパイラ作ってくれ >>534
お前アホだろ w
方向性がおかしいって話だぞ >>535
現代の言語でジェネリクスをサポートするのは一般的
テンプレートをこねくり回して整数演算をするのはおかしいという意味なら、普通の構文で書けるconstexprが追加されたからそっちを使うように >>536
costexprで階乗書いてみてから言えよ constexpr unsigned long long factorial(int n){
unsigned long long r=1;
for(int i=1;i<=n;++i){r*=i;}
return r;
}
うん、簡単だね!
たまにソースコードを見て、あ、この数字なんだっけって考えるよりも
10000回コンパイルさせるほうが早いと思うよ
>>540
オーバーフローのチェックがないからやり直し。 はーい
constexpr unsigned long long unsafe_factorial(int n){
unsigned long long r=1;
for(int i=1;i<=n;++i){r*=i;}
return r;
}
constexpr int min_factorialable(){
for(int i=1;;++i){
if(unsafe_factorial(i) > unsafe_factorial(i+1)){ return i; }
}
}
constexpr unsigned long long factorial(int n){
if (n < 0 || n > min_factorialable()) { return 0; }
return unsafe_factorial(n);
}
>>529
実行時計算で答え算出してそれを貼った方が楽じゃね? >>548
なんでそんなめんどくさくてミスしそうな方法をチョイスするんだよ 551デフォルトの名無しさん2018/03/12(月) 01:21:50.18
>>548
計算&書き換え手順をマニュアル化して、何十種類の仕向け別にバージョンアップの度に人海戦術で計算&書き換え&コードレビュー&テストするんですね、わかります min_factorialable() は、階乗を正しく計算できる最大の値を返す
constexprな関数(コンパイル時にint定数に置き換えられることを期待)、
と読み取ったんだけど、なぜにmin_なの?
553デフォルトの名無しさん2018/03/12(月) 05:41:37.75
上限を求めるときに使うのはminだから、かな
知らんけど
最初min_nonfactorialableでnon取った時に直し忘れました
一日の秒数を86400と書いてたらマジックナンバーやめろと言われたんだけど、
プログラムを少しでも書く人間にとってその数字は常識でいいよね?
60*60*24 と書いて「その60とか24は何だ?」と言われないでしょ?
それと同じレベルだと思ってるんだけど。
うるう秒でクラッシュするクソソフトウェアの出来あがり
ニュートン力学と天文学と暦学からやりなおした方がいい
>>555
言われないとわからない奴は言ってもわからないだろうから
お前は一生マジックナンバー使いまくりでいいぞ >>558
欲しいね
chronoが中途半端でイラつく >>556
それだと 60*60*24 と書いても同じだよね。
うるう秒とかは関係ない定数管理してる場合の話ですよもちろん。 >>557
86400がプログラマの常識的にマジックナンバーなのかどうか、って話ですよ 所で皆さんmakefileはどう編集してます
あまり触れていないようなので気になります
>>562
趣味では汎用のmakefile作ってそれを使い回してる
仕事ではautotools 他人と共有するコードならなるべく要素を分解して分かりやすく書いた方が好ましい
2の倍数も直接記述するのではなくシフト演算使った方が綺麗
くくるんじゃなくて…
クラス宣言
int main()
{....}
あとは c++ スレで
常識なんて集団が変われば変わる
そのコードを見せる事を想定した集団の常識かどうかを考えろ
2進数8進数10進数16進数のみではないということ
60進数や24進数の話でしょ時計を語るときは必須の常識
集団の常識ってことなら、'86400' をマジックナンバーと思ってる人間は少数派っぽいので、
文句はやんわりと無視する方向で行きますわ
というかマジックナンバー言われるのって数字の意味とか集団の常識とかじゃなく書式の問題だよね
計算式の中に定数ポン置きしてる書き方してる奴がチームにいたらそりゃマズいよ、変数とか定数に置き換えろって俺も言う
定数を定数に置き換えるってなんだよ
リテラルは定数なり変数なりにって感じで読み替えといて
>>572
しかしこうはしないだろ?
const int int8_bits = 8;
uint16_t word = (hi << int8_bits) | lo;
こうもしない
const int sec_per_min = 60;
int sec = m * sec_per_min + s;
数値リテラルで書くのが許容される数値というものがある
sec = day * 86400 はどうかというのが>>561
個人的には知らない人でも暗算もせずに初見で合ってるかどうかわかるか、
を基本にすべきだと思う (小さな2の冪乗は除く。2の冪乗知らん奴はシネ) uint16_t word = (hi << CHAR_BIT) | lo;
これCHAR_BIT != 8な環境を意識するんなら、16って書いてあるのも問題だね
const int micro_per_sec = 1000000;
int us = sec * micro_per_sec;
こう書けって言われたら俺はお断りする
>>575
bit_per_char や shortでもintでもなく int8、uint16_t と明記したのは所与の仕様のつもり。
最近のapiはよくナノ秒返してくるから1000000000 倍
1000.0*1000*1000と分かち書きしたくなる 時刻を自動的に合わせますというコマンドボタンを作って
押すだけで済むのに
>>577
それを言うなら1'000'000'000だろjk 86400って書くと、ideで定義の参照も使えんし
86400で検索したときに
1日の秒数なのか、適当に決めたタイムアウトとかの秒数なのか、ただのIDなのか、連番で出てきただけの数値なのかとか、無意味な数列なのかまざってわからんくなるやろ
#define SEC_PER_DAY (60*60*24)
なんてやる人いないのかな
>>581
#define は基本使わない、int const ABC = 12345; なら時々使う さっさとこう書けるようにしてくれ
今の<chrono>クソすぎんよ
int sec_par_day = static_cast<int>(std::chrono::second{std::chrono::day{{1}});
86400とか1440でわかるけど
24*60*60とか24*60って書けばいいだけだと思う
21世紀も5分の1が過ぎようかっていうこの時代に
何が悲しゅうてたかが時刻を扱うだけでtime_pointの他にtmやらtime_tやらをガチャガチャさせられにゃならんのだよまったく
589デフォルトの名無しさん2018/03/13(火) 22:08:40.50
86400って何のために使うんだろう
うるう日とかうるう秒とか考慮しなきゃ気持ち悪くね?
考慮する必要性があるものかどうかが分からないからなんとも
例えば時系列データをその時点から1日分の数を使うというものなら閏秒を考える必要がないし
592デフォルトの名無しさん2018/03/13(火) 22:28:43.21
int t = 86400; // 24*60*60
これで解決
閏秒の有無等で可変のものなら可変のものなりの書き方するでしょ
計算して変数に入れるとか
問題は不変の数値定数をどう正規化して書くか、正規化する必要はあるか。
24*60*60 派の人と 60*60*24 派の人が両方プロジェクト内にいたらなんか嫌だな
プロジェクトで誰かが決めたらそれに従うよ
派閥作るほどの問題じゃないでしょ
絡むわけじゃないけど
決めたら従うのは当たり前で、それが「決める」ってことだろ。
派閥の話じゃなく混ざってたら気持ち悪いってことが言いたかったんだよ。
あっちこっちに書き散らすものじゃないから混ざってるとかあり得ない
1カ所になるまでリファクタリングしろ
気持ち悪いと思うかどうかは感性の問題だからなあ
例えばある日地球の回転速度が変わって1分が61秒になった
プログラムを修正しろと言われて、
場所によって書き方が違っていると大変だね
と言う話なら理解出来るけど
constexpr int min = 60;
constexpr int hour = min * 60;
constexpr int day = hour * 24;
hoursは<chrono>にあるだろ
それとoperator""h
operator""dayがねえんだよな<chrono>って
chronoのhoursはstd::chrono::duration<int, std::ratio<3600>>のエイリアスなので
daysはこうすればよい
using days = std::chrono::duration<int, std::ratio<86400>>
>>602
> daysはこうすればよい
> using days = std::chrono::duration<int, std::ratio<86400>>
>>555へ戻る w 閏秒を考慮するのと1日を86400秒とするのは全く関係ないのに閏秒がどうとか言い出した奴が悪いのでは
丁寧に書くなら計算の根拠として60*60*24を見えるところに書いておけばいい
知ってる知識を披露したかっただけだろうから罪は軽い
606デフォルトの名無しさん2018/03/14(水) 10:28:48.31
ほぼ関係ないな、難癖もいいとこ
実用上は全く関係ない
うるう秒がどうのこうのと言う、問題じゃなく86400秒をそこでしか使わないって根拠が無いんだよね
後でまたその数値が出てくるとしてその度に86400と書くのか、もしその数値を修正する事になったら全部書き直すのか、2回3回使うようになって始めて変数なり定数なりに入れるのか
それなら最初から式中に出てくる数値は変数に格納してから使えって統一した方が話が早い
今時マジックナンバーとか昭和からタイムスリップしてきたのかよ
プログラムにおけるマジックナンバー(英: magic number、魔法の数字)とは、何らかの識別子もしくは定数として用いられる、プログラムのソースコード中に書かれた具体的な数値である。
そのプログラムを書いた時点では製作者は数値の意図を把握しているが、他のプログラマーまたは製作者本人がマジックナンバーの意図を忘れたときに閲覧すると「この数字の意味はわからないが、とにかくプログラムは正しく動く。
まるで魔法の数字だ」という皮肉を含む。
by Wikipedia
「1日の秒数」って定数を86400って書いて怒られたって話じゃないんだ?
>>609
じゃあオマエ、構造化もしてないのか?
昭和時代ほど耳にしなくなっても廃れたのではない話は結構あるぞ >>611
怒られたという程じゃなくて、
一日の秒数 = 86400;
と書いたら「マジックナンバーやめろ」と言われたってことさ >>615
そうじゃなくて
60*60*24 て書いて欲しいんだってさー
謎 >>616
まぁ可読性高くて損する事は無いし、なるべく要素は分解して書いた方がいいんじゃないの
何かどうしても86400じゃなきゃ困る理由とかあるなら話は別だろうけど、無いだろ? ITのエンジニアって
こういうくだらないことで
給料貰ってるんだろうなあ
こういうクソみたいなことでもウンチク垂れてテコ入れしろと提案することにより仕事してます感かもし出す為だろうな
>>619
結果のわからない投機的な模索をしているときは
逆にマジックナンバー地獄なコードだよ
他人に渡すコードを清書するときの書き方・考え方とは真逆 俺がわかるからみんなわかるだろうというコードはすげー困るな
例えその場の全員がわかったとしても今後わからない奴が出てきた時の事を考えて
できうるかぎりわかりやすいコードを書くべきだな
そのためのコストにもよる
空想論じみた「わかりやすさ」にまで付き合ってらんないこともある
特に最低限のプロとしてのスキルを欠く者を想定することはしない
ちょっと飛躍するがプログラム言語だってそうなっている
マシンの性能を使いやすさに振るということを無限にはやらない
どのくらいのアホまで付き合ってやるのか性能とのトレードオフで
色んなバランスで棲み分けになっている
まぁ別に自分だけが使う分にはいくら分かりづらく書いてくれても構わんけどな
86400を60*60*24と書くことにはなんのコストも支払ってないから書けばいいな
いちいち話を飛躍させる奴はなんなんだ
人によっては>>599みたいにしろって言うだろうし
結局は人それぞれってことじゃないの
16を2*2*2*2っていちいち書く人はいないでしょ
まぁ1<<4って書けと言われるかもしれんが 学校の試験問題で一日の秒数としてソースに86400を書いたら
マジックナンバーだからと減点された、納得いかない。
みたいな発端じゃないのかなぁ。
それをfindとsedでやる勇気あるか?
たとえば俺なんかは1箇所ずつよく見て有機的に判断しないと怖いし
それの残業代は貰えるのか心配だ
当然その程度のリファクタリングはするべきだしそもそもマジックナンバーをどうにかするべきだし
お前の残業代とかいう飛躍した話はどうでもいい
飛躍じゃねえ実話だよ
ずいぶん昔、社内BBSでそれ系のことを言い出したやつが
偉い人から突っ込まれてた
プロとか言い出してる人がいるけど、それこそ飛躍では?
プログラムの話題から外れてきていると思いませんか?
>>614
だからわかりきってるかどうかは人によって違うって話
プログラムの前に日本語の勉強しろよ w まぁコスト次第で可読性を犠牲にするケースもあるだろうけど
この場合はメモリ食う訳でも処理遅くなる訳でもソースの構造が変わる訳でもない
86400でも十分分かりやすいかも知れんが60*60*24なら更に分かりやすくなる
どっちが良いかなんて議論の余地無いよね
>>631
別にプロでなくてもいいんだけどさ
おまえさんなりに、同じプロジェクトにいて欲しくない足手まといが
どのくらいから下というのはあるだろ >>626
> 16を2*2*2*2っていちいち書く人はいないでしょ
> まぁ1<<4って書けと言われるかもしれんが
状況次第だろ
場合分けの条件が4個あって各々2状態をとるとかなら2*2*2*2って書くかもしれない
下から4ビット目のマスクが欲しいなら1<<4って書くこともある シフト使うな、ビットフィールドで書け
なんて言われると、俺は相手にもよるが逆らいそう
>>637
ビットフィールドは割り付け順序が処理系定義だったりしたからあまり使ったことがない たまには2進リテラルちゃんのことも思い出してあげてください
議論の本筋(1日の秒数として即値で86400と書くことの是非)とはさらに離れるけど、
ビットシフトを使う定数は常にカッコで囲んでくれ。
res = a + 1<<4 + b;
res = a +(1<<4)+ b;
642デフォルトの名無しさん2018/03/15(木) 07:15:43.22
>>641
3つ以上の項があると静的解析ツールで怒られるから
res = (a +(1<<4))+ b;
と書く >>641
下のつもりで上書いたらただのバグじゃん 算術と混用するときは結合順位に注意せよ、というだけのことを
いちいち必ずだ!ルールだ!と金切り声で吠えついてくるやつはウザい
>>642
可読性悪くしてかえって品質低下招きそうな指摘だな vectorをつなげる際、copyが良いとか、insertを使えとか色々書いてあるのですが、どれが良いのでしょうか?
あらかじめ領域を広げておく必要があるけどinsertの方がチェックが入らない分速い
insertの直前にreserveって意味あるのか?
reserveは終端のポインタが更新されないからresizeじゃないとだめ
reserveしてback_inserterでcopy
>>648
insertはサイズチェックしてるでしょ。
>>649
iteratorを2つ受け取るタイプのinsertなら意味あるんじゃね?
>>650
resizeは不味いだろ。 >>652
insertの中で追加数数えてreserveと同じことしてるでしょ
まさかループで一個ずつ挿入なんて実装はあるまい >>655
失礼。挿入位置のiteratorもあるから、3つ受け取るタイプの誤り。 >>657
カンマ演算子とdecltypeでコンパイル時に評価される
decltypeの中身を左から順に評価し、結果は一番右の型が帰る
この場合はa+bの型が評価出来ればbool、できなければSFINAE >>657
>a + b
a + bが可能かどうか調べる
>,
次の式を評価する
>bool()
bool型の初期値を返す
つまりdecltype(a + b, bool())はa + bでSFINAEをしつつカンマ演算子でdecltypeにbool型の値を与えて返り値の型をbool型にしている decltypeで,も使えたんですね。一番右の型が帰るということはdecltype(a+b,a-b,a*b,a/b,bool())とかしてもよさそう。。。
自分ではその機能を説明してるページを見つけれませんでした。
ありがとうございます。
>>660-661
それで良いのか。 いいこと知った。
いちいち enable_if をしとったわ。 >>656
a.reserve(a.size()+b.size());
a.insert(a.end(),b.begin(),b.end());
こんな感じのことをやるのかと思ったんだけど、これ意味ないでしょ? >>664
declとはdeclareの略であることを考えると a.reserve(a.size()+b.size());
copy(b.begin(),b.end(),back_inserter(a));
>>665
random iteratorの場合の特殊化実装がありました。ごめんなさい >>662
decltype comma trickでググれ まあoperator,()が定義されてるとまずいんだけどな
インスタンスにdeleteかけたとき、メンバ変数が破壊されるのとデストラクタが実行されるのはどっちが先?
今書いてるコードがデストラクタでメンバ変数アクセスすると落ちることがあるから、破壊されるのが先なんだろうか?
>>671
原則としては構築の逆順って覚えておくと間違えない。 >>671
delete this; とかしてませんか、これは基本的に避けたほうがいい >>673に同意。確保と破棄は生ポインタを触らずに自動化した方がいい。スマートポインタとかコンテナとか。
二回deleteを避けるためにポインタにNULLを代入する技もある。 そろそろNULLは駆逐してnullptrに移行させたい
>今書いてるコードがデストラクタでメンバ変数アクセスすると落ちることがある
へ〜んなの
ていうかメモリを壊しているかすでにdeleteされた死骸を再deleteしてるとしか、
>二回deleteを避けるためにポインタにNULLを代入
OpenCVのC言語インターフェースのやつ、
678デフォルトの名無しさん2018/03/19(月) 23:06:01.35
>>678
区切り文字を読まないとfail状態になってそれ以降は失敗し続けるので止まってしまうということですかね std::getline()は読み込んだ文字列に改行文字を含めないから
行末まできちんと読んだのか
文字数カウントのせいで読み込みが行の途中でぶちきれたのか
直ちにはわからないといいうアホウな仕様
判別には結局std::basic_istream<T>::unget()の助けが要る
C++標準ライブラリのうちストリーム関連だけは腐っているからC言語のを使いなしゃれ
※ 個人の感想です
訂正
△: C++標準ライブラリのうちストリーム関連だけは腐っているからC言語のを使いなしゃれ
◎: C++標準ライブラリのうちストリーム関連だけは本当に腐っているからC言語のを使いなしゃれ
入出力はCもC++もクソまみれだからなぁ
ちょっとコンソール出力を整形しようとして、あの肥溜めのクソくだらない落とし穴地獄にいちいち付き合わされた結果
プログラミングそのものが嫌いになる人達が山のようにいるのが本当に残念だ
自分が知ってる昔はいっぱいいたけど
最近だとスクリプト言語から先に入るから減ってるのかね?
オブジェクトの外部表現を型ごとに定義できる iostream は悪くない設計だと思うんだけどなぁ。
ローカライズに向いてない。
打鍵数が倍増どころじゃない。
モダン言語はみなprintfライクだしねー
printf()は便利ではあるが桁を揃えて出す時に面倒になることもある。
特にこの頃は UTF-8 で漢字混ざりだと文字幅とバイト数または文字数が一致しない。
そもそもそんなものの一致をあてにすること自体が間違いかも知れないが、Unicode
には一応 HALF WIDTH, FULL WIDTH 等があるんだから何とかしてこれを生かした
フォーマッタが欲しいところではある。
>>672
>>673
あるクラスがあって、その中でスレッド立ててるの
それでクラスのデストラクタが呼ばれたら、メンバ変数のスレッドポインタをつかってスレッドcancel->joinってやろうとしてて
それでjoin呼ぶあたりで落ちるんだよね
作られた逆順ってことはデストラクタのほうが先に実行かな?それだとメンバ変数はいきてるよね streamはコンソールの入出力のためだけにあるわけじゃないから
つーてもcoutだってsetw/setfillはあんまり使いやすくないしなあ
operator<<をユーザー定義できるのはありがたいけどね
>>688
デストラクタの実行中はそのクラスとその派生元クラスのメンバ変数はまだ使える
必ず落ちるならデバッガでバックトレース見てみたら? 別の原因に見える
まずデストラクタじゃなくて普通のメンバ関数で明示的に呼んで止めた時に大丈夫か確認してはどうか
pthread_cancel はいろんなことがよく分かっている人しか使ってはいけない
>>685
「<<」と「>>」の2種類しか用意できんやんけ
それらを表示と入力に割り当ててしまえば結局シリアライズのための固有なメソッドなりインターフェースなりを別途作らねばならんぬ、
そもそもの構想からして頓挫してゐる、
頓挫してゐるのだ…! >>694
表示用とシリアライズ用はストリームの性質で切り替える筋合いのものだろ?
シリアライズ用のストリーム型を用意してオーバーロードすればいいんじゃね。 ちょっなんで数億年の生物史史上はじめて
ようやっとSTDINとSTDOUTとSTDERRの3種類に世界が抽象化されたストリームという概念|を
細分化するという元の木阿弥にしますか;;
藻前は
some_command | tee result.txt > some_file.bin
とかいったパイプやリダイレクトを表示専用とかシリアライズ専用とかに分けたいのかっていうか、
>>696
お前は何を言ってるんだ。
ここで言ってるストリームは C++ 用語のストリームだぞ。
「ストリーム『型』」ってわざわざ書いてるんだからわかれよ。
下位レイヤでは好きなところに繋げればいい。 streamとstreambufの違いを理解しよう
要するに std::basic_ostream を継承した何かを作ればいいんだ。
ストリームはもう捨てたほうが良いぞ。
おじさんからの警告だ。
便利そうに見えて便利に使えない
それがstream
>>696
カンブリア紀からオルドビス紀にかけて行われた抽象化は
今でいうインターフェイスの考え方で、当たり前だが
インターフェイスを継承する実装クラスは無数にあってよい
そういうのは元の木阿弥とは言わないぞ >>696
さっき >>698 で説明した C++ の話題を置くとしても、
(まあ C++ スレで C++ の話題を置いちゃうのはどうかと思うが)
標準入力、標準出力、標準エラー出力のみっつしかないってことはない。
エラー出力をリダイレクトするときに 2> って書くの、どういう意味だと思ってる?
2 はファイルディスクリプタな。
デフォでオープンされてるのが 0, 1, 2 ってだけで、やりたければ 3 でも 4 でも使っていい。 >>705
空いているディスクリプタが使用されるとしても、自分で特定の数字を指定してディスクリプタにすることはできなかったんじゃなかったかな? >>706
失礼、dup2() というのがあったね… coutがSTDOUTにつながってるだけでここは何につなげてもいいということ
streambufの中身はただの配列でもいいし、アプリケーションのロガーでもいいし、循環バッファでもいいし、通信のポートでもいい
シリアライズするときはバイナリ表現にしたいし
ログするときは文字列表記にしたいし
>>709
だからそれはストリームオブジェクトの型で切り替えろって言ってるんだろうが それを嫌だって言ってんだよ
バイナリの読み書きは write() だの read() で十分
read なり write なりを「使う」のは別にいいよ。
それを C++ 上でどのように抽象化すればいいかって話なんだから。
そういうレイヤの違う話を混ぜ込んでくるなよ。
そこで新しい型を設けてまで << を使う意味がない
cout にバイナリでシリアライズするときはどうすんの?
size_t serialize(const T& t, ostream& os)
とかを各型用に書く方がマシ
バイナリでシリアライズするに際して
別の型のストリームオブジェクトを作ってまで
<< だの dec だの endl を使えるようにすることの利点を説明して欲しい
例外を除いて
operator<<()は書式化出力
write()は非書式化出力
なのでバイナリを出力するときはwrite()を使うべき
>size_t serialize(const T& t, ostream& os)
シリアライズのような複雑な操作をするときはこれは悪い選択じゃない
というかstreamそのものを放り込むのはたまに見かける
>>715
書式化 (formatted) ってのと、結果がバイナリかというのは直行する概念だよ。
シリアライズってのはオブジェクトのバイト列をそのまま出力することじゃなくて、
バイナリ形式の特定のフォーマットにして出力することだろ。
それは書式化って言うんだよ。 >>714
マニピュレータを使える意味はないかもな。
使えないように定義することも出来るし、意味がないなら使えないようにしておくべき。
ここでは抽象化の話をしているんだ。
出力先が人向けのテキスト表現であるか機械向けのシリアライズ表現であるかによって
書き方を変えなきゃならない、相手を意識しなきゃならないというよりは、
相手によって自動で切り替わって欲しいってことなんだよ。
意識しなくていいデザインってのは意識しにくくなるってことと表裏一体だから、
見えなくなるのが気にくわないってのならわかる。 無意味な処理が嫌だとか言っておきながら
ここでは無駄の塊みたいな方法を勧める
アホですね
>>721
俺は一貫して抽象化の話をしてるつもりなんだが。
プログラマの意図を表現できる書き方をすべきって話をしてんの。
無意味な処理をしろと書いてあるのをプログラマの意図として読み取っていいのか?
そうじゃないだろう。
C++ がせっかく用意しているライブラリを活用するのが無駄なのか?
そうじゃないだろう。 ハッキリ言ってストリームは蛇足だったわ。
廃止したほうが良いわ。
Boostもそうだけど、有り余るC++のパワーをカッコよく使いこなそうとしてやっちまったみたいな。
もうちょっと使う側の立場にたつべきだな。
黒魔術だなんだ言って楽しめないようではC++は向いていない
蛇足ねえ。。。
禿本1stでoperator overloadのデモ用に作られたサンプルなんだが
そういうのは後で取って付けた存在といえるのか?
業界全体としては奥の深さを求める人(求道者)を一か所に集め留めるのには非常に有益な言語
そのうちAsioやRangeあたりも標準化されるだろうし
もうその方向に突き抜けてほしい
使いやすい言語なんか他にいくらでもある
具体的にどういうときに不便なのか語れよ。
使いにくいってだけじゃ何にもわからん。
C++に関しては慣れてない人がそう言ってるだけだから
>>726
どの資料だったか覚えてないけど、演算子オーバーロードに関して
先生は「元の演算子の意味とかけ離れた挙動をさせるのは避けるべきだ」
みたいなことも書いてるよな。
まぁ、原則は指針であって絶対の規則じゃないわけだけど、
<< >> をビットシフトからストリーム入出力に振り替えておいて
どの口で言うか、このハゲッー! とか思ったり。 >>731
ストリームのような周知の事実になっているものはそれには当てはまらないでしょ >>731-732
まああれくらいのものになると、オブジェクトに追加で突っ込んでいくような動作が「元の演算子の意味」になっちゃってるよな。
そんなことより C++20 に入る予定のカレンダーでは日付を 2018y/mar/22 とか書けるらしくて、
これはさすがにクソやろ……。
これもいずれ普通に受け入れる気持ちになるだろうか。 >>733
既にfilesystemのpathが/で階層作れるから
current_path / "aho" / "baka"みたいに
C++の演算子は連想ゲームだ >>731
あの頃の禿はreverse_iteratorなんて思いもよらず
operator+が減算の動作をすることを否定してたね >>733
日付の表記は何種類かあるし年/月/日でも日/年/月でも表せるなら結構便利だと思う。 >>733
標準に「日付を表す型」みたいのが追加され、
それ用リテラルの接尾語(のひとつ)が ""y で 2018y は2018年を表す、
さらにこの型では / は日付要素を区切る演算子としてオーバーロードされてる。
…といった感じか?
確かに虚心坦懐に / を見れば、割り算のコンピュータ向け代用記号だけでなく
日付の区切りや、ファイルシステムの階層区切りでもあるけど。 こんだけ演算子は深いのになぜか未だに[]は引数を一つしか取れない
「静的」、「動的」というのがよく分からないのですが、詳しく書いてある本はありますか?
ヒープ領域がどうたらとかいうのもよく分かりません。
スタックとかいうのもよく分かりません。
詳しく解説している本を教えてください。
ロベールのC++の本を読んでいて疑問に思いました。
五曜は対応してくれると有り難いかも知れないけど
他はいらんな
>>740
C/C++ のメモリ構造について、になります。
これは基本的な事項で、初級を脱するためにはぜひとも必要な知識なんですが、
そのわりにあまりに解説されることがないような気がします
適切な説明がないものか… >>740
まず、メモリの管理方法として
1. スタックエリア、に格納するやり方
2. ヒープエリア、に格納するやり方
の大きく分けて二通りがあり、
2. ヒープエリア、二格納するやり方について
2-1. 「静的」:static キーワードを使うやり方
2-1. 「動的」:malloc()/free() または new/delete を使うやり方
が分類されます。 >>746-747
ありがとうございました。
あまりそういう本はないんですか。
もしかしたら、ヘネシーらのコンピュータのハードの本とか読まないといけないんですかね?
あるいはコンパイラの本ですかね? >>747
一般的に、静的領域をヒープとは呼ばんだろ こういうのはネットで覚えたからどういう本に書いてあるかはわからん
>>749
手っ取り早いのは「マシン語」を書いてみる、マシン語(アセンブリ言語)のルーチンを C にリンクさせる、ていうのが王道ですが、
昨今はマシン語のいい教科書がない、という気がします
gcc のインラインアセンブラとかが有望だとは思いますが、まあ簡単にマシン語を記述している教材なんていうものが思いつかない、マシン語の需要というか動機がないのかもしれませんが >>750
うーむ、たしかに static を「ヒープ」とは言わないかもしれませんね… >>752
ありがとうございました。
マシン語の本を探してみます。
>>751
ありがとうございました。
本に書いていない場合には仕方がないのでネットで調べてみることにします。 どうだろ?
C++ の言語仕様的にはオブジェクトの寿命に違いがあるだけで、
それを実現するメカニズムについては詳細な規定があるわけではない。
まずは C++ のパラダイムの中で理解を深めれば自然に理解できるんじゃないの?
手を広げすぎても収集が付かなくなる気もするんだけどなぁ。
マシン語に手を出すのは飛躍しすぎだしやめといた方がいい。ある程度C++になれてより深く理解したいと思うようになってからがいいよ。
動的、静的は大雑把に言えば、コンパイル時つまりソースを書いた時点で決まるものを静的、実行時に変化するものを静的と呼ぶ。
変数の型とかメモリ領域の確保の仕方とか、いろんな文脈で使われる。
>>756
決まる、決まらないの主語は何でしょうか? メモリについて知りたいんならC言語から始めたら良い
Unixの移植目的で設計されたC言語は、実行効率のためほとんど必然的にメモリが透けて見える言語になったんである
『プログラミング言語C』という名著もある
これの後ろの方のmalloc()の実装サンプルまで通読したら
シングルCPUの範疇ならメモリについて嫌でもワカル
『プログラミング言語C++』と違って三日もあれば読めれる手頃な分量やしな!
>>758
横だが。
何でも、だよ。
型なら静的型、動的型というし、メモリ確保なら静的確保、動的確保という。
マシン語は飛躍しすぎ。
CのエンハンスとしてC++を使うのならマシン語(インラインアセンブラ)もありだが、
C++をJava/C#/C++の並びで使うつもりならインラインアセンブラとか禁止でしょ。
というかそもそもその辺が分からない=全くの初心者がC++からやろうというのが間違い。
PythonかRubyあたりから始めとけ。(どっちも俺は知らんけど) コンパイラがコンパイル時に決めるものが静的、出来上がったプログラムを実行した時に決まるのが動的
C++だとそういう理解の方がわかりやすいと思う
マクロ、テンプレート、constexpr、リテラル、式や変数や関数やクラスの宣言型なんかは静的
静的なものは全部コンパイラが決めるからプログラムの実行時にはいちいち計算しないし、バグで決められなかったらコンパイラが怒る
変数やインスタンスの中身、関数呼び出し、仮想クラスのオブジェクト型なんかは動的
実行環境や食わせた入力・ファイルなんかに依存するからプログラムを実行してみないと決まらない
動的なバグはコンパイラは感知できないから客先でプログラムを実行するとクラッシュする
適当だけどだいたいこんな感じ
細かいようだが、
コンパイル時に確定=静的
実行時に確定=動的(=コンパイル時に確定できない)
で若干の例外(staticとか)があるが大体あってる。
「プログラミング言語C」はやめとけ。名著だが、あれは
「既にプログラミングを出来る人が、C言語を学ぶ」用であって、全くの初心者じゃ読めない。
「プログラミング言語C++」も止めとけ。あれも「既にCを使える人が…」で以下同文。
他本は総じてゴミなのも事実だが。
特定のアドレスにデータを配置して割り込みかける必要があるからじゃないだろか。
予約語のstaticは転用されまくってわけわからなくなってるので
「静的」とソースコード上のstaticは全く別物だと思った方がいい
その辺整理されないんだろうかね
そう言うものだという説明で
不本意ながら納得する事何十年
そんなに混乱するか?例外としてしまって問題ないと思うが。
俺は規格には詳しくないが、(というより色々混ざってしまっているが)
・Cのstatic関数=ファイルスコープに限定、externの反対 --- (A)
はC++ではなんとかされたのではなかったっけ?(どうせ使わないからどうでもいいが)
・staticクラス、あるいはクラスのstaticメソッド --- (B)
は「静的」で矛盾しないから、そもそも問題ない。
・関数内static変数でプチグローバル(みたいなやつ) --- (C)
も普通にクラスにしろ、って話でしかないし、使わないだろ。
結果、普通に使う分には特に混乱しないと思うが。
文法オタクは気にするのかもしれんが。
(C)は「動的関数にしよう」という意図があったのかもしれんが、
結局C/C++の世界は静的関数しかないから、意味無かったし。
というかそもそも俺は動的関数のメリットがよく分からん。
C#は動的関数だが、結局ロード/アンロードはアセンブリ単位=ほぼ起動時に纏めて、
であって、活用してない。
Javaは動的関数でメリットを享受してるんだっけ?(知らんから教えて)
https://ideone.com/Epp30z
お兄ちゃん助けて、コンパイルが通らないの。
VCで開発してます。
jsonのメモリーモデル研究にとりあえずシェアードPTRの組んでそれからやっぱユニークPTRの変更しました。
色々いじってるのですが、意味不明なエラーが出てさっぱりわかりません。
自前のコードなら自分でどうにかするのですが、コードステップするとライブラリの中でえらーおこしててさっぱりです。
どなたかご教示ください。お願いします。 std::vector<UniqueObject>にstd::pair<UniqueObject,UniqueObject>突っ込もうとしてんじゃん
ちゃんとエラーメッセージ読めよ
static関数は恐らくリンク工程がdynamicの場合があるため
それに対してのstaticなんだろな
毎回思うんだけど、なんでgccで勉強しようとするんだろうな。
エラーメッセージ読めと言われても読めるわけがない。
一番わかりにくいメッセージを出すコンパイラで勉強する子が不憫でならない。
772デフォルトの名無しさん2018/03/24(土) 04:28:06.63
確かに書いてあるな。
じゃあエラーメッセージ読めよ。
775デフォルトの名無しさん2018/03/24(土) 06:12:32.26
いつも大量のWarningが出るのを真面目に対処せず放置してるからErrorが出ても理解できない罠
static_castの動作内容は翻訳時に全て確定する
dynamic_castの動作内容は実行時のvtableにより変化する
static_assertは翻訳時に検査を行う
assertは実行時に検査を行う
static link libraryは翻訳時に結合する
dynamic link libraryは実行時に読み込む
>>778
質問者はそれ以前の、プログラミング一般の「静的」「動的」の区別が付いてない。
スレ移動しても意味無い。というかどこのスレでも同じ。
C++のstaticは、Cのグダグダな仕様を引きずっているからおかしくなっているだけで、
C++で新たに設定されたstaticは他言語とも整合取れてる。
これに関しては「Cが悪い」でいいと思うよ。
説明している本が無いのは、そもそもそんなところで引っかからないだろう。
教習所でハイオクの話をしても意味無い。
一通り動く物を組めるようになるまではそれにフォーカスしろ、でいい。 静的動的の区別は大事だし引っかかりやすい所でもあるでしょ
テンプレート引数に変数突っ込んでなんで動かないのぉぉとか初心者はよくあるよ
説明してる本がないって本当か?本当なら世の本がクソすぎる
で、静的と動的の違いは何なんだよ。
ガンダムで説明してくれ。
ガンダムで説明できないうちは理解できてることにならないぞ。
>>783
じゃあお前が説明しろよ。
お前は馬鹿だから出来ないと思うがな。
そもそも>>763は誰向けのレスだよ? コーディング規約にchar aznable禁止っていうのを見たことあるから
C++にガンダム要素を入れるのはタブー
>>780
> テンプレート引数に変数突っ込んでなんで動かないのぉぉとか初心者はよくあるよ
ねえよ
> 説明してる本がないって本当か?本当なら世の本がクソすぎる
世の本は概して糞だ。これは事実だ。
というかここら辺の認識がずれるのは世代ギャップだ。
現状の本を書いてきている世代は全員CをやってからC++をやっている。
だから「静的」「動的」の区別が付かない状態でテンプレートを触ることがなかった。
当然そこを解説した本もそんなにあるはずがない。
お前らの世代がCをやらずにいきなりC++を始め、それで色々苦労した経験があるのなら、
お前らの世代の連中が本を書かなければならない。ただそれ以前に、
俺はその必要(全くの初心者がCをやらずにC++を始める)があるとは思えないが。
入門書を書いている連中はプログラマでも宣教師でもなく、ただのテクニカルライタだ。
だから需要(売れる)があれば書くだけ。今無いのは需要がないと見られているから。
俺もこの見方については同意する。
最初のプログラミング言語がC++ってのは単純に選択を間違えてる。 C++とJavascript以外学ぶ必要があるとは思えない。
>>789
それはさすがに世間が狭すぎる
土方志望としてもJava程度は触っとけ Javaは当初の理念を失ってしまったように感じる。
JavaはJVM上で動く一言語に成り下がったからな
みなさん、ありがとうございました。
カーニハン他の本をまず読んでみようと思います。
>>793
そうなんですか?
Robert SedgewickらのAlgorithmsという教科書がJavaで書かれているため、
Javaの本も買って読んでいます。
ところで、学術的?な本では、オブジェクト指向言語としてC++かJavaが
大抵使われていますが、C#は使われていません。これはマイクロソフト
という一企業が設計した言語だからでしょうか? たとえば、プログラミングコンテスト関係の本では大抵C++が使われています。
そういう理由から、本当はC++ではなくC# + Visual Studioを勉強したいのですが、
C++の本(ロベール)を買って読んでいます。
そのうち大抵の言語は経験なくてもリファレンス片手に使えるようになるから好きなもん使え
>>796
なら素直にC#やっとけ。
その後に必要ならC++で何も問題ない。
C#は商業的につまずいたのでJavaほどの知名度はないが、
言語自体はJavaよりは断然いい。(後発だから当然だが) ねーねー。
STL作った人は、共産主義国で食中毒にあって、ベッドの上で朦朧とした頭で閃いたって話だった気がしたけど、どっかにその話のソースある?
ググっても見つからないよー
皆様ありがとーございます。
論文の枕で書こうかと思いまして
char* str = "abc";
とは書かずに、
const char* str = "abc";
と常に書くようにと本に書いてあります。
理由は文字列リテラルは直接書き換えてはいけないからであると書かれています。
●コンパイルは通っても、実行するとエラーになることもある。
●同じ内容の他の文字列リテラルまで書き換えられてしまうことがある。
とも書かれています。
禁止されているにもかかわらず、コンパイルが通る可能性があるというのはどういう
ことなのでしょうか?
(1)コンパイルエラーが発生
(2)コンパイルは通るが実行するとエラーが発生
(3)コンパイルは通り、実行してもエラーが発生しないが、同じ内容の他の文字列
リテラルまで書き換えられてしまうという不具合が起こることがある。
コンパイラーの設計者には、(1)、(2)、(3)の選択肢があるのはなぜでしょうか?
禁止されているのだから、一律にコンパイルエラーにするのが自然に思われます。 👀
Rock54: Caution(BBR-MD5:0be15ced7fbdb9fdb4d0ce1929c1b82f)
const char* str = "abc";
const char ca[] = {'a', 'b', 'c', '\0'};
の二つは同じことだと思っていましたが、これは違うということでしょうか?
const char* str = "abc";
では、"abc"をある場所に格納しておき、それを使いまわしたりすることがある
ということでしょうか?
例えば、
const char* str1 = "abc";
const char* str2 = "abc";
と書いたときに、 str1 == str2 になることがあるということでしょうか?
一方、
const char ca1[] = {'a', 'b', 'c', '\0'};
const char ca2[] = {'a', 'b', 'c', '\0'};
と書いた場合には、それぞれ、別に格納場所が確保されるということでしょうか? 👀
Rock54: Caution(BBR-MD5:0be15ced7fbdb9fdb4d0ce1929c1b82f)
すみません。
カーニハンらの本の日本語版のp.127に書いてありました。
char amessage[] = "now is the time";
char *pmessage = "now is the time";
の違いについてです。
そして、文字列の内容を変えようとすると、その結果は不定となる
と書かれいます。なぜ不定としているのかについては理由は書いてありません。
>>809
ありがとうございました。
故意に違反状態にするということもあるんですね。
正直言って無駄に分かりにくいところがあるんですね。 うん過去のもうメンテナンス不能なコードは膨大なんでそうするしか仕方ないんだよ
814デフォルトの名無しさん2018/03/25(日) 13:01:03.23
C++相談室で出す話題でもなかろに
816デフォルトの名無しさん2018/03/25(日) 13:52:43.26
>>810
旧K&Rつまり第一版は書換可能だったの 818デフォルトの名無しさん2018/03/25(日) 15:22:53.51
C++スレでK&Rの話すんなや
>>807
ISO/IEC14882:2017 C.1.1の段落3で
char* p = "abc"; // valid in C, invalid in C++
となっているので、C++ではコンパイルが通ってはいけない
なぜ通ることがあるのかというと、
JIS X3014:2003 D.4で
定値文字列からの暗黙変換 文字列リテラルに対し,定値から非定値へ暗黙変換することは,推奨しない(4.2参照)。
となっており、C++03に従う限りコンパイルは通ることになっていた名残だ するなと言われてもスーパーセットなんだからC言語の記法がどこまで通じるかは重大な問題だと思う
>>820
スーパーセットにするというよりは、
つかず離れずというポジションかなぁ。
C++ が先にやったのを C で取り入れたことも有るし。 可変長配列とか名前付きの構造体初期化とかc++に取り込まれたんだっけ?
スーパーセットは20年前にとっくに終わったんじゃないかと。
すでに導入されてたらスマソ
>>823
たぶん入ってないな。
可変長配列 (VLA) って確か C でもオプショナルに格下げされてただろ。 (C11 から)
C++ のイニシャライザはだいぶん複雑になっちゃったから辻褄の合うようにするの大変だろうし、
もうやらないんじゃないかな。 実用レベルではほぼスーパーセットといっても差し支えない
826デフォルトの名無しさん2018/03/26(月) 11:51:36.03
実用レベルではCがC++のサブセットだし🙄
実用レベル:=C++にも存在する機能に制限されたC
C11の_GenericとかそれCで敢えてやる必要あるの?って思う
微妙に使い辛い機能だし分からんでもないけど、本当の名前がちゃんと見えてるのはちょっと安心感
>>828
スイッチで選択するのをスマートにした感じやな。
イマイチ〜〜。
テンプレート一個書いて複数にジェネレートさせる方が好み。 あるクラスAのラッパークラスWで
A&を受け取る場合はWの全てのメソッドが使えて
const A&を受け取る場合はWのconstメソッドだけが使えるように制限する設計って
ありましたっけ?
あとは operator -> でポインタ返すやり方とかだな
834デフォルトの名無しさん2018/03/27(火) 06:53:48.55
>>831
制限っていうのは、コンパイルエラーにしたいの? A a0;
const A a1;
W w0(a0);//OK
W w1(a1);//NG
const W w2(a1);//OK
const W w3(a0);//OK
で、Wの非constメソッドには必ずconstメソッドが対応して存在している
みたいな
837デフォルトの名無しさん2018/03/27(火) 07:35:02.82
>>835
NGっていうのは、コンパイルエラーにしたいの? >>836
明確な欠点を指摘出来ない時に使う言葉だな
「ダサい」 クラスを
W
MutableW (変更可能なW)
と分けるのがよく使われる現実的な解だと思う
MutableW は W の派生型として実装すると楽
>>835
>で、Wの非constメソッドには必ずconstメソッドが対応して存在している
この部分は意味不明なので聞かなかったことにしておく >>831
テンプレートにしておいて SFINAE で分岐するという方法はとれるが……。 845デフォルトの名無しさん2018/03/28(水) 20:50:12.70
>>843
言語ヲタなんてプロジェクトに一人いれば十分だし
兵隊は言語の知識よりコミュニケーション能力、報連相、Excel方眼紙スキルが大事よ 848デフォルトの名無しさん2018/03/28(水) 22:29:42.33
上司なんか関係ないやろ
お客さんを味方に付けることや
上司も客も関係無いよバカども
プログラミングの話だバカども
visualstudio2017 Win32アプリケーションでSQLiteを使いたいのですが
Nugetにそれらしきものが合ったのでインストールしようとしたのですが以下のエラーでインストールできません。
https://www.nuget.org/packages/SQLite/
パッケージ 'SQLite 3.13.0' をインストールできませんでした。このパッケージを 'native,Version=v0.0' を対象とするプロジェクトにインストールしようとしていますが、
そのフレームワークと互換性があるアセンブリ参照またはコンテンツ ファイルがパッケージに含まれていません。
どうすればよいのでしょうか。 CoAppのタイムスタンプ調べてみて。
NuGetは捨てろ。
代わりに何を使うか。
VCPKG。
ただし、MSは三年後にVCPKGも捨てているだろう。
逆に我々がVSを捨てる時期に来ている。
MSの方針としてC++を捨ててC#に移行させるというのがあって、C++ユーザーはあの手この手で改宗を迫られる。
もはやVSでC++は苦行。
というか、WindowsでC++が苦行。
C++を捨ててC#に移行するか、Windowsを捨ててOSXかLinuxに移行するか。
二択。
WindowsではC#が正解。
なぜならMSがそれを望んでいるから。
C++のチームも頑張って更新してるけどな
IDEとコンパイラは十分なのに
・パッケージマネージャーがクソ
・再起動しないとPATHが更新されない
・VSのプロジェクトが用意されていないとビルドが面倒
と環境が整備されてなさすぎる
C# + C++/CLI + C++
という選択肢
我々が間違っている公算も高い。
我々はC++を使いこなせる。
だから、C++なら簡単にできるのになぜそうしない?と思ってしまうが、これから学ぶならC#のほうが簡単だろう。
MSがC#を推すのは正しいのかもしれない。
C#はビジネス用だから
より早く大量にコードを生産することを目的としているからC++とは用途が違う
Android でも iPhone でも Windows でも使える共通部分のコードは c++ で、
ってのを C# に変えたいのかもしれんが
別段 c++ で不自由ないしなあ…
てか c# って .Net のイメージ強すぎて単体で使える気がまるでしない
未だにproperty実装出来ていないC++標準仕様が異常なんだぜ
そりゃMSも堪忍の尾が切れるってもんだぜ
ら、ライブラリで実装できるから・・・。
ちなみに、プロパティっぽい提案は過去出てるが、全くテーブルに乗らない。
C#はいい言語だよ
Linq便利だし
ただC++とは用途が違うってだけ
何度聞いてもプロパティが欲しいという思いが沸かないんだが
ウィンドーズホンでネイティブC++とC++/CXの間を取り持つwrapperを書くのに使う
Wrapperを書くのに便利
プロパティが使えたらMFCのような糞環境でUpdateDataを使わなくてよくなる
プロパティに代入で表示が変わり
プロパティからそのまま値が取り出せる
しかしVisual Studioは何だってUTF-8で保存されるのをそんなに嫌うんだろうか。
あの手この手でUTF-8で保存するのを妨害してくるけど。
VSで開発してLinuxに移植されるのを嫌がってるんだろうかね。
その割にはgdbと接続できるようにしてるし。
>>869
ナイナイ
今だって setFoo() だの getFoo() だの実装すりゃできるけど初学者以外はやらないだろ?
実装するにも使うにも効率が悪いからね。 >>869
それはsetter/getterではできないことなんだな? a.Hoge+=100;
みたいな事をできて便利だなと思うことはあるけど無けりゃないでいいわレベル
プロパティはメソッドともフィールドとも区別できるメタデータとしての活用が唯一の動機なんだが
結局のところ実行時の型システムまで整備しないととただの構文糖だしなあ
>>873
A.Width+=20;
と
A.setWidth(A.getWidth()+20);
どっちがいい?; a.value++とかif(a.Width==100)とか
普通に書けるものをわざわざgetter setter書きたいんだな
変ってる
UI とのバインディングを失笑されたら
シンタックスシュガーでこんなに楽にかける!と主張し始めたよw
そりゃ楽にかけて便利だよな。
そのためのものだもの。そこは同意する
GUIだけじゃなくて他にも使えるというか
他がメイン
>>878
そういう風にお手軽にメンバを書き換えるのは事故のもとなのでやめましょうってことでめんどくさくしたのに
戦争を知らない世代みたいな
現状でもa.value()++とかif(a.Width()==100)でできるしな
これまでのコードとの一貫性を破壊してなおかつ年代物のコンパイラに更に複雑なパースをさせて得られるものがちょっと括弧を省略するだけとは プロパティのメリットは最初publicで適当に実装しといても後からgetter/setter付きのprivateに変えれる所じゃない?
変数がない状態でもテストに通るように作るべきだからpublicで変数を持たせる機会が一瞬もない
C++builderってプロパティなかったっけ。
たいそう便利だったような気がするのだが、思い違いだろか。
そもそも最近のGUIビルダってC++ビルダーの影響受けまくってるような感じがする。
トップダウンで理想から考えるのが早い
どういう風に書ければ満足するんだ
>>881
パースが面倒になるとは思えない
変数と同じ使い方なんだから変数のようにパースするだけだと思うが…
それにお前はコンパイラつくらないじゃん c++0x()以降の理念で仕様策定だけしたらいいじゃん
基本機能を妨げないように仕様追加
使うかどうかは本人次第
誰も強制しない
拡張forもautoも馬鹿みたいに文句言ってたけど今でも使うなって言う人はいるのかな
>>887
これらを採択する人の中にGCCやMSVCの人がいないわけないじゃん
関数として扱うのか、変数として扱うのか決めなきゃいけない
そしてどうやってポインタをとるのかなど色々な問題がある
そしてさっきも言ったけど括弧を少し減らせるだけでできることが増えるわけじゃないというのが最大の問題 得意げにご高説を垂れ流してる最中に申し訳ありませんが
a.value++;
と
a.value()++;
は別物
あえてみんなスルーしてくれてるのに
ん?
参照した値を変えるとGUIの表示とか更新してくれんの?
getterとsetterあったとして実行してくれんの?
a.width()とa.widthが同じgetter的な動作してくれるのはわかるけど
a.value()++; が参照返しとかどんだけヘボいんだよw
リファレンサのprvalueだろjk
プロパティ不要とは言うけどそもそものプロパティの仕組みと効果はわかってないんだね
こんな人ばかり
何スレか前にもプロパティの議論あったんだけどね・・
少なくともgetter/setterを自動生成する、みたいなクソな機能ではないぞ
>>884
Builderだけtry-finallyセクション使えたり次元が違う希ガス >>876
A.extendWidth(20);
それを書くことが便利で必要なクラスだったらそういう操作を作るべきだな >>884
あったよ
>>904も含めて当時はネイティブコードを吐くC#みたいな感じだった
もう少し頑張れるかと思ったけど、Visual Studioの便利さに負けたと思ってる カーンを首にしてアプリ側に振ったのが敗因だったな
膨大なdbaseの資産も全く使えなかったのはNetaWareと
同じだった
>>908
違うよ。
デフォルトでのゲッタ/セッタを提供したりすることはあるけども、 >>903 で言及している通り「変数に見せかける」機能。 そもそも変数に見せかけると言うプロパティ自体の話とgetter/setterの自動生成の話は全く別物で>>902で比較してる意味がわからん
たぶん本人もちゃんと理解できてないんだろうな... >>909
なんだそういうことか。それも含めて単なる自動生成だと認識してたよ。 そうやってソフトが重くなって行くわけだな
数値の += なんて軽いと思って何度も呼んだら
実は描画や保存も何度も呼ばれてしまうとか
プロパティってそれ単体で取り出せるの?
それなら使えるな
呼ばれる側 : そんな何度も呼ばれるとは思わなかった
呼ぶ側 : 重いとは思わなかった
少なくともAdd()なら何かしらの関数を呼んでいることはわかる
プロパティでもなんらかの関数が含んでいることはわかるが
それがただの変数なのかプロパティなのかは調べるまでわからない
変数でも演算子がオーバーロードされてる場合もあるからな
結局調べないとダメ
っていうか>>883いわく、publicな変数は有り得ないらしいし、そういう運用してるなら考えるまでもなくプロパティじゃん >>910
お前のレスの意味がわからん
実際C#もソースコード公開されてるソフトの改造程度にしか触ったことないんでちゃんと理解してないが
getter/setterの自動生成するだけのクソ機能と誤解してる人がこのスレでも前スレでも見られたから
>>902を書いただけなんだが
というか書き込む前の1〜2レスすら読めんのかお前は C++erが通常prvalueで返しているリファレンサを、データメンバにするってことなら
テンポラリを作らなくなる分、速度的なメリットはありそうだな
# でも、俺はイヤだな
# データメンバがドカドカ増えるのがなんか気持ち悪い
# 慣れの問題っちゃそうかも知れんが
>>923
だからそんな誤解してるのはお前と同レベルのバカだけだろ w
言語仕様の話とIDEの機能の区別もつかないアホなんて放置でいい Javaのイメージなのかな?
あれはJavaBeansとかいうゴミ規約のせいで本当にGetXX()とSetXX()を作るだけのゴミ機能がIDEに標準装備だったりする
まあプロパティある言語触ったことないやつは勉強不足だから無視していいって言うのは一理ある
>>930
現状のメンバへの代入や値取得が
暗黙的に作られるgetter/setter
プロパティが採用されてもこの辺はなんら変わらないかと お前らの書き込み見ると、プロパティがものすごい大発明なんじゃないかと錯覚するけど
変数のようにかける件を含めても糖衣構文以上のものじゃないだろ。
+=したけりゃそういうプロキシ書けばいい。
これ以上言語機能を増やさなくて良い
コンパイラが規格に追い付いてなくて互換性が崩れる
クソ機能というわけではないが、ものすごく便利というわけでもない
あればあったで使うけど、ないならないで困らないし、言語設計として採用するしないの判断はどっちもあり
C++は採用しない判断をした
その程度の話
938デフォルトの名無しさん2018/03/30(金) 23:12:27.73
実体が関数なら漢らしく見た目も関数にしろよwww
見た目が変数なのに処理が走るとか、見た目が割り算なのに文字列連結するとか変態野郎は死にくされやwwwww
その辺はC++のコンストラクタ・デストラクタに嫌悪感を示すCユーザーが昔よく言ってた台詞と似てるw
「裏で何が起きてるかわかりづらいから嫌だ」、とかね
別に本気でプロパティ推してるわけじゃないが、いざプロキシクラスで代用しようとするとめんどい
ETなんかを仲介するとテンプレートの実体化の数でコンパイラへの負担がデカいし、
メンバ関数の呼び出しをサポートしようとすると継承が必要になるし・・・それなりに問題点はある
>>934
大発明じゃなくて、もはや常識。C++にはないって聞いて最初驚いたもん
いやまあたしかになくてもいいんだけど、演算子オーバロードはあるのにプロパティはないって変な言語だわ ダイヤモンド継承使われてるんだっけ
あれ使ったことないな
いらない機能だと思うなら使わないってだけだしプロパティはあった方がらくだと思うけどね
独自拡張でつけてるのもあるし
iostreamの<<チェーンが実は最近まで規格上未定義動作だった話は正直呆れた
採択されてもプロパティのアドレスをどうやって取るのかっていうことで標準化委員会で揉めて10年は停滞する
>>948
最初のプロパティの提案がいつかはしらないけど
実際にこれが決まったとして最短で2020年
そこから更に何年かかるのか 抽象クラス"Super"から派生した子クラス、"A", "B", "C"があったとします。
Super* obj1 = new A();
Super* obj2 = new B();
Super* obj3 = new C();
訳あって動的に作成したインスタンスobj1〜3を一度deleteしたのち
再び同じ子クラスでインスタンスを作成しようと思います。
obj2がクラスBのインスタンスであることが一目で分からない場合に
obj2がクラスBのインスタンスであることを突き止め、一度deleteし、
再度クラスBでインスタンスを作成する方法はあるでしょうか?
ちなみに必死に考えて考えついた方法ですが
クラスA, B, Cにそれぞれ「私はAクラスです」「私はBクラスです」みたいな
文字列を出力する共通メソッドをpublicで作成し、そのメソッドを実行して
帰ってきた文字列からそれがどのクラスのインスタンスか判別が付くのではないかなと思いました。
決してスマートな方法とは言えませんが・・・
もっとスマートな方法はありますか?
class B : public Super
{
public:
Super* re_new() override
{
delete this;
return new B{};
}
};
>>948
単純に &obj.int_prop と書いた時に、この式の型と値をどうするかは難しい問題じゃない?
intの一時オブジェクトへのポインタ、intのぬるぽ、int_propのgetterへの関数メンバポインタ、ill-formed
どれも問題あると思う プロパティを関数として実装したら関数のアドレスは取れるんじゃないかなぁ。はぁ、実装依存ですか。
>>950
全然スマートじゃないがvisitorパターン使えば? >>953
> 単純に &obj.int_prop と書いた時に、この式の型と値をどうするかは難しい問題じゃない?
エラーにしちゃえばいいだろ つまり意識しなきゃならんてことか
じゃあ素直に関数にしろよ
>>953
一時オブジェクトへのポインタってことにする一択だと思うけどなぁ。
あくまでも「変数に見せかける」、
つまりは、ゲッタの呼出しに構文糖を付けて見かけ上だけ変数 (データメンバ) っぽいって立場を貫かないと、
余計な気を回してもわかり難さが増すだけだよ。
rvalue なのは仕方がない。 どうしてアドレスを取りたがるのかよくわからない
クラスのメンバ関数だってアドレス取れないだろ
>>959
メンバ関数のポインタ構文が何故あるのですか? 取れるよ、何言ってんの
そのポインタは動的結合までできる優れもの
>>959
変数に見せかける以上は変数と同じようにふるまうことを期待するってのは普通の要求じゃないか?
データメンバに対して操作するテンプレートはプロパティを操作するテンプレートとしても使えて欲しい。
でもまあ充分に「見せかける」ことが出来ないのなら問答無用でエラーになった方がマシではあるかもしれん。 objがlvalueなのにobj.int_propがrvalueになるのはまずいと思うんだよなあ
うっかり関数の戻り値でその参照なんか返そうものなら相当わかりにくいバグになる
C#とかはその辺の問題どう解決してるのかしらね
property int count {
>>() {return count_ ; } // getter
<<(int cnt) {SetCount(cnt):} // setter
&() {return &count_;} // address getter
};
みたいにアドレス抽出用のメソッドを追加すりゃ良いだけのような気がする
コードを減らす為の規格追加でコードを増やす解決法
う〜ん
>>969
これは抽象化の話なんだよ。
変数のように見せかけるためには何が必要かって話なの。 property int count {
() {return count_ ; } // getter
=(int cnt) {SetCount(cnt):} // setter
&() {return &count_;} // address getter
++() {return ++count; } // incrementer
}
この方がしっくり来るな
予約語を増やすとどれだけの影響があるか
なんて考えたことはないのかな?
まあここはC++相談室
おれが考えた最強言語を語るところじゃない
opaque definition でゲッタを定義できるように拡張すればプロパティ専用の構文を導入する必要なく
プロパティを実現できるのではないかと妄想していた。
using count = int {
() {return count_ ; } // getter
=(int cnt) {SetCount(cnt):} // setter
&() {return &count_;} // address getter
++() {return ++count; } // incrementer
};
予約語増やさないならこんな感じに書けなくもない
プロパティの実装の議論までここでするか?
Dと同じでいいじゃん
前提が違うものを同じには出来ないよ。
参考にすることはあると思うけど。
仮想関数のアドレスが取れないという発言は何だったんだろう
>>950
std::pair<Super*,std::string> obj2 = std::make_pair(new B(), "ClassB"); 982デフォルトの名無しさん2018/03/31(土) 13:50:16.75
>>950
クラスA, B, Cにそれぞれ自分自身のインスタンスを生成するstaticメソッドを用意し、
そのstaticメソッドへのポインタを返す共通メソッドを用意する。 リフレクションがある言語でGUIの画面またはユーザーコントロールを作成する際に
YSIWYGで作ることをやれるIDEを作りたい、というときに、メンバー関数とプロパティーの2種類あったら便利なのや
C++にプロパティー入れたらリフレクションも来るでこれは…
もっとも上記課題解決のための技術は10年も前にWPFの登場で丸ごと過去の技術やがな…
ていうかWPFのコンバーターの書き方とか、メンバ関数に逆戻りやぞ…
(IValueConverter.Convert(), IValueConverter.ConvertBack(),
IMultiValueConverter.Conver(), IMultiValueConverter.ConvertBack(), ...
リフレクションはゴミとまで言わないけどc++にはいらない機能
リフレクションがあれば死なずに済んだ人もいるだろうに。
c++のfriendはprivateメンバーすべてにアクセスできてしまうけど特定の変数だけ、もしくは特定の関数だけfriendにする事は可能でしょうか?
>>990
ピンプるか、○○って俺の友達の友達なんだぜーにしてしまうか、かなー pimplイデオムはなんとなくわかるけど、俺の友達の友達は編集したい対象を別のクラスに分けてしまうこと?
そういえばシステムハンガリアンはしばしば批判されるのに、pimplのpは批判されているのを見たことがないな。
>>995
そこは「ハンガリアンじゃなくて半刈りやん」って言って欲しかった。 999デフォルトの名無しさん2018/04/02(月) 11:52:25.29
>>998
WYSIWYGのtypoなだけやん
アスペか lud20221222062026ca
このスレへの固定リンク: http://5chb.net/r/tech/1516406742/ヒント:5chスレのurlに
http://xxxx.5ch
b.net/xxxx のように
bを入れるだけでここでスレ保存、閲覧できます。
TOPへ TOPへ
全掲示板一覧 この掲示板へ 人気スレ |
Youtube 動画
>50
>100
>200
>300
>500
>1000枚
新着画像
↓「C++相談室 part134 ->画像>2枚 」を見た人も見ています:
・C++相談室 part152
・C++相談室 part153
・C++相談室 part154
・C++相談室 part156
・C++相談室 part155
・C++相談室 part148
・C++相談室 part124
・C++相談室 part157
・C++相談室 part126
・C++相談室 part143
・C++相談室 part160
・C++相談室 part150
・C++相談室 part142
・C++相談室 part133
・C++相談室 part137
・C++相談室 part147
・C++相談室 part144
・C++相談室 part149
・C++相談室 part138
・C++相談室 part146
・C++相談室 part163
・C++相談室 part141
・C++相談室 part137
・C++相談室 part130
・C++相談室 part140
・C++相談室 part117
・C++相談室 part135
・C++相談室 part139
・C++相談室 part132
・C++Builder相談室 Part21
・0からの、超初心者C++相談室
・C++相談室 part131 [無断転載禁止]
・Cygwin + MinGW + GCC 相談室 Part 8
・Cygwin + MinGW + GCC 相談室 Part 3
・C♯相談室 Part20
・C言語相談室(上級者専用)
・屯田五目須のお悩み相談室
・Mac G5 中古買入相談室
・河田さんによる人生相談教室
・自営業 悩みごと相談室 16
・C#, C♯, C#相談室 Part93
・自営業 悩みごと相談室 40
・MFC相談室 mfc23d.dll
・自営業 悩みごと相談室 52
・C#, C♯, C#相談室 Part91
・C#, C♯, C#相談室 Part94
・C#, C♯, C#相談室 Part79
・自営業 悩みごと相談室 47
・C#, C♯, C#相談室 Part91
・自営業 悩みごと相談室 45
・C#, C♯, C#相談室 Part95
・自営業 悩みごと相談室 48
・C#, C♯, C#相談室 Part75
・C#, C♯, C#相談室 Part90
・自営業 悩みごと相談室 51
・自営業 悩みごと相談室 41
・自営業 悩みごと相談室 46
・C#, C♯, C#相談室 Part94
・0からの、超初心者C言語相談室
・自営業 悩みごと相談室 50
・自営業 悩みごと相談室 49
・ライダーマンのお悩み相談室
・C#, C♯, C#相談室 Part95
・自営業 悩みごと相談室 43_
・【男飯】Rickの相談室【言霊】
00:28:26 up 8 days, 10:52, 0 users, load average: 7.15, 8.86, 9.10
in 0.081046104431152 sec
@0.081046104431152@0b7 on 122014
|