C++相談室 part94

このエントリーをはてなブックマークに追加
536デフォルトの名無しさん
API上別にしないといけないってどういう事?
あるタイミングで i を使って、別のタイミングで d を使うって事?
使ったかどうか覚えておけばいいだけのような
537デフォルトの名無しさん:2012/04/14(土) 13:15:17.88
>>534
APIって何?WinAPI? 自作エンジン操作するAPIとか?
538デフォルトの名無しさん:2012/04/14(土) 13:26:28.24
とりあえず、実際に使う部分を見せて欲しいな
関数名が秘密ならそのあたりは変えていいから
539デフォルトの名無しさん:2012/04/14(土) 13:35:58.11
>>535
イテレータ内部でストリームを basic_istream<charT,traits>* in_stream; で保持しておいて
return lhs.in_stream == rhs.in_stream; するのがstdでのやりかた
540デフォルトの名無しさん:2012/04/14(土) 13:45:03.82
>>524
こんな感じ?
http://ideone.com/n5AKA

541524:2012/04/14(土) 14:43:12.69
寝てたんで見るのがおそくなった。すまん。

>>540
が綺麗なんで、APIを変えることにしました。
単体の列をストリームで扱えるようにしたかったんだけど、
行ごとに読み込むストリームのほうがたしかに自然だな。
可変テンプレート引数をとるようにして(my_iter<int,double,double>)
tuple<int,double,double>が値になるようにすればテーブル読み込みできるね。
read()を書くのがちと面倒くさそうだが。
542デフォルトの名無しさん:2012/04/14(土) 18:04:19.59
template <typename T, typename U>
void f(tuple<T,U>& t) {...}
template <typename T, typename U>
void f(pair<T,U>& t) { f(tuple<T,U>(t)); }
みたいな多重定義を避けられる方法ってないですか?

ただし、なんでも受け付けちゃう
template <class PairType>
void f(PairType& t) {...}
ってのは無しで。

(コンパイルでtuple<int,int,int>をつっこんでたらエラーが出るように)
543541:2012/04/14(土) 18:15:50.84
>>542
template <typename T, typename U, template <typename...> pair_type>
void f(pair_type<T,U>& t) {...}
かなぁ・・・他にいい案があったら教えて下さい。
544デフォルトの名無しさん:2012/04/14(土) 18:35:55.99
template<typename T,typename U>struct pair{〜;operator tuple<T,U>&(){return tuple<T,U>(*this);}};
545541:2012/04/14(土) 18:42:36.84
std::pairの仕様みてもそんなの無いんですが、暗黙の変換をどっかで定義しろってことですか?
546デフォルトの名無しさん:2012/04/14(土) 18:52:58.80
>>542

template<class T, class U> class tuple
{
  ・・省略・・
  tuple( const std::pair< T, U > value ){省略}
  ・・省略・・
};

もしくは、

template<class T, class U> tuple<T, U> to_tuple( const std::pair &value )
{
  return tuple< T, U >( value );
}

547デフォルトの名無しさん:2012/04/14(土) 19:11:59.04
c++0xにstd::tupleというのがあってだな・・・
スレ違いの話題で混乱させてしまってすみませんでした。
548デフォルトの名無しさん:2012/04/14(土) 19:27:08.97
脳内でネームスペースを勝手に補完したらダメだよね。
549デフォルトの名無しさん:2012/04/14(土) 19:35:16.21
m(__)m
550デフォルトの名無しさん:2012/04/14(土) 19:50:26.85
c++0x ってどんな風に入力したらこうなるんだ?
551デフォルトの名無しさん:2012/04/14(土) 20:02:17.12
俺はSTLマスターだが質問あるか?
552デフォルトの名無しさん:2012/04/14(土) 20:05:47.40
ないわー
553デフォルトの名無しさん:2012/04/14(土) 21:18:41.74
ないない
554デフォルトの名無しさん:2012/04/14(土) 22:30:07.35
>>551
std::messagesってどうやってつかうの?
555デフォルトの名無しさん:2012/04/14(土) 23:16:35.57
std::set<T>のインスタンス同士の一致比較(つまり、同一の集合であることの確認)ってどうやるの?
T型の要素はソートされて格納されるそうだから
インスタンスをa, bとして、a.begin()〜a.end()までとb.begin()〜b.end()をそれぞれ比較して
全部一致することと同値なのだろうか
それとも、STLの仕様的にはそこまでは保証されておらず、上の方法はたまたまうまくいっているか、処理系依存で、
やはり比較前に自前でaやbに格納されている要素をソート等せねばならないのだろうか
556デフォルトの名無しさん:2012/04/15(日) 03:03:52.36
結論だけいうと==でやれ
557デフォルトの名無しさん:2012/04/15(日) 10:29:58.92
> インスタンスをa, bとして、a.begin()〜a.end()までとb.begin()〜b.end()をそれぞれ比較して
> 全部一致することと同値なのだろうか

同値でしょ。

要素値を比較する前に双方の要素数を比較した方が良さそうな気がする。
// 要素数チェック
if(a.size()!=b.size()) return(1);
558デフォルトの名無しさん:2012/04/15(日) 11:38:51.16
mismatchでやれ
559デフォルトの名無しさん:2012/04/15(日) 14:56:31.96
比較オブジェクトが同一かも検査したほうがいいんじゃないか?
560555:2012/04/15(日) 15:52:01.26
レスdクス
とりあえず要素となる型に<演算子が定義されていれば
(ていうかstd::set<T>のTの用件なのでそもそも定義されている前提)
少なくともVS2010では>556の方法で逝けるみたいです!

STLのマニュアルとして↓ここ見ながらやってたんですが、
http://www.cplusplus.com/reference/stl/
グローバル関数でset<T>& operator==(set<T>&, set<T>&)が定義されるとか
どこにも書いてなかったから気づかなかったorz
561555:2012/04/15(日) 15:54:45.55
訂正
誤: set<T>& operator==(set<T>&, set<T>&)
正: bool operator==(const set<T>&, const set<T>&)
562デフォルトの名無しさん:2012/04/15(日) 16:06:06.28
std::setは赤黒木。
赤黒木は同一要素からなる集合に対してはbegin() 〜 end()までの順序構造も同じ。
だから単にsizeを見た後iteratorを回してoperator ==での直接比較か
operator <(or operator >)x2で同値比較すればよい。
563555:2012/04/15(日) 16:22:00.26
スマン>560でボケたことを書いたorz
要素型Tのless than演算子(operator<())だけでは
一致比較できるわけないじゃんorz(多分bool operator==(const T& a, const T& b)が必要)

set<int> a, b;についてはa==bで一致判定できましたが
Tが自作クラスの場合は要検証です検証中なう
564デフォルトの名無しさん:2012/04/15(日) 16:35:32.67
大抵赤黒木で実装されるけど
赤黒木でなければならないと規格で決められているわけでもない
565デフォルトの名無しさん:2012/04/15(日) 16:42:12.29
>563 !(a<b) && !(b<a) だな。562も書いてるけど。
566デフォルトの名無しさん:2012/04/15(日) 16:46:30.43
>>565
a,bの間に全順序の存在しか仮定しないときに、
果たしてそのコードでa==bと同値になるのか
冷静に考え直したほうがいいんジャマイカ、
567デフォルトの名無しさん:2012/04/15(日) 16:59:04.51
いやすまん>565でいいのかorz (!(x<y) && !(x>y)) ⇔ (x≧y && x≦y)⇔ (x == y)
結局、Tについてoperator<()が定義されていれば、
set<T> a, b; についてa==bできるっぽい
(実際Tを自作クラスとしても、Tのoperator<()を定義したらVS2010で動いた)
568デフォルトの名無しさん:2012/04/15(日) 19:59:18.77
std::setのoperator==ではstd::equalが使われstd::equalでは>>555のように比較される
というようなことをごちゃごちゃ書きたくなかったから>>556みたいにレスしたけど
ちゃんと解説したほうがよかったな

http://www.cplusplus.com/reference/stl/set/operators/
ここにも書いてあるぞよく読め
569デフォルトの名無しさん:2012/04/15(日) 20:21:33.47
>std::setのoperator==ではstd::equalが使われstd::equalでは>>555のように比較される
なるほど、、いつどのアルゴリズムを使うのかきちんと決まってるのか
std::equalの定義(というか規格上の等価テンプレート)みたら、
Tについてstd::equalが使われる場合、Tについてoperator==()は必須みたいですね
>567の最後の行は撤回(実はoperator==()が定義されてた)
570デフォルトの名無しさん:2012/04/16(月) 00:14:55.06
最近C++を勉強しだしたんだが
とりあえず学んだ範囲で簡単な電卓を作ってみたけど
なんか自信がないw動くけど 無駄な事してないかとか
ツッコミを入れて欲しい
http://codepad.org/uz46AcHY
571デフォルトの名無しさん:2012/04/16(月) 02:15:07.23
>>570
・グローバル変数の使用は避ける。
・calculatorの中で初期化とされてるのは初期化でなく代入。初期化と代入は別物。
・なぜcalcuratorの中でanswerに代入(初期化)?

・// a:Aの値。
 ソースを先頭から読んだ場合この時点ではAの値といわれてもなんなのか不明。
・// Yと回答されたらループ、それ以外は終了。
 実際の処理との不一致。
572デフォルトの名無しさん:2012/04/16(月) 06:28:57.57
このコードに限らずだが広域でのusing namespaceが個人的にヤダな
せめて関数の中でusing namespaceするか、using std::cout;の様に
取り込んどいて欲しい。std系統じゃぶつかりづらいがVectorとか
Listとかありふれた名前は簡単にぶつかる。
573570:2012/04/16(月) 16:33:06.78
ツッコミありがとうございます
それをを受けて直してみました
http://codepad.org/T1qZFJTB

using namespace std;はまだ私にとって「おまじない」でしかないので
std:: を省略できるなら使うか みたいな感じなので・・・
574デフォルトの名無しさん:2012/04/16(月) 20:12:09.41
男ならヘッダファイルでusing namespace std;
575デフォルトの名無しさん:2012/04/16(月) 20:32:28.10
>>574
そんな男気あふれるあなたにC言語
576デフォルトの名無しさん:2012/04/16(月) 22:05:18.63
>>574
ダメ! ゼッタイ!!
577デフォルトの名無しさん:2012/04/16(月) 23:39:54.67
>574は漏れもやったが30分で悔い改めた
それはそうと、デカいオブジェクトの実体をSTLのコンテナに格納して
複数個所から参照しつつ必要に応じて追加するということをしたいんだけど
コンテナにinsert()する前後で参照が有効であり続けるようなうまいやり方ってないですかね…
コンテナの要素型を自作クラスでうまく作ればできなくは無いけど標準的なやり方は?
578デフォルトの名無しさん:2012/04/16(月) 23:46:58.49
std::listを使う
579デフォルトの名無しさん:2012/04/17(火) 00:18:51.98
using namespace std; がヘッダに書いてあるライブラリを使うことを強制されているんだ!
windows.h が自動的にインクルードされていたり、まさに地獄だぜ。

>>577
listを使うか、間接参照するか
580デフォルトの名無しさん:2012/04/17(火) 00:24:37.62
マクロ展開出力みたいに
ADL展開出力オプション欲しいよな
581デフォルトの名無しさん:2012/04/17(火) 02:41:59.29
>>577

なんでもかんでもshared_ptrでくるんじまいなよ! コンテナ用件は自動的に満たされるぜ!
582デフォルトの名無しさん:2012/04/17(火) 05:47:00.52
using namespace std; をわざわざincludeするようのヘッダー作ってincludeしまくってるわ
とりあえずusing std::stringとかにかえてみた
583デフォルトの名無しさん:2012/04/17(火) 06:57:21.79
お前の using namespace std; のせいで
ライブラリのヘッダでコンパイルエラーが出たわ
584デフォルトの名無しさん:2012/04/17(火) 09:46:42.23
しかしこのcodepad、まさかの強制using namespace std;である

http://codepad.org/wzgxNgw9
http://codepad.org/PSECxXqW
585デフォルトの名無しさん:2012/04/17(火) 10:06:09.92
全部std::付けたり関数毎に書くのは面倒なので自分の名前空間内でusing namespaceしてる
http://ideone.com/uXfYk
http://ideone.com/IiwPB
586デフォルトの名無しさん:2012/04/17(火) 12:38:41.41
using namespaceはよほどのことがない限り使わないな。
namespace fs = boost::filesystem;
とかはよくやるが。
587デフォルトの名無しさん:2012/04/17(火) 13:24:50.23
そんなこともできるんだったな
すっかり忘れてた
588デフォルトの名無しさん:2012/04/17(火) 13:32:52.26
using namespaceを使っといて、完成版では置換すればよい。
手間の問題。
589デフォルトの名無しさん:2012/04/17(火) 21:48:04.95
using namespace したものを置換するのは困難だぞ
590デフォルトの名無しさん:2012/04/17(火) 22:09:49.45
テストコードをそのまま本番に持って行ってるわけね
591デフォルトの名無しさん:2012/04/17(火) 22:26:19.01
class Sample
{
 const bool aaa(const a, const b) const
 const int bbb(const c) const
 const Sample(const d) const
}

最近constに触れる機会があったのですが

TYPEはintとかfloatとか
【const TYPE】 aaa(const x) const

質問なのですが、【const TYPE】の部分がconstだと
実際にはどういう利点があるのでしょうか
他の部分がconstになっていると
色々とパフォーマンスに影響がありそうだと直感的に理解できるのですが

(変数には値とかコピーが入るわけですよね?)
戻り値の型にconstがあったからといって特に意味無いような気がしてしまいまして

じゃあ、頭のconstにはどんな意味があるんじゃ!? ということで疑問が湧いてしまったのですが
どなたか意味というか意義というか、教えてくださいまし
592デフォルトの名無しさん:2012/04/17(火) 22:29:04.87
const TYPE&じゃなくてconst TYPEなの?
593デフォルトの名無しさん:2012/04/17(火) 22:29:55.14
>>581
>なんでもかんでもshared_ptrでくるんじまいなよ!
何を言いたいのかわからんが、
確かに「型Tのset」のかわりに「型Tのshared_ptrのset」にでもして
shared_ptr<T>のoperator<()とoperator==()を(適当なスコープで)定義するとしたら逝けそうですな
※ とにかくデカいオブジェクトなので同じものを複数持ちたくない。
  当然insert時は重複チェックをやる。これをも極力高速、極力コンテナに任せにしたいからlistというのもちょっと、、、

>577における「コンテナの要素型を自作クラスでうまく作」るのより良さげな回答だけど
しかしshared_ptrはSTL標準ではないのではないか
594デフォルトの名無しさん:2012/04/17(火) 22:37:54.44
>>591
const病の伝染をやり過ごせる利点がある

class Sample {
  int* p;
  // (適当な構築子)
  const int* GetPtrA() { return p; }
  const int* GetPtrB() const { return p; }
};
であるとして、
  const Sample foo(...);   // constオブジェクトとして構成
  int* p1 = foo.GetPtrA();  // コンパイル時エラー
  int* p2 = foo.GetPtrB();  // おk
  
595594:2012/04/17(火) 22:41:43.73
ああスマン頭のconstか
わからんメリットなど無いのではないか
(でもテンプレート絡みでちょっとあるのかも?テンプレートについて人類は何一つ断言できない)
596デフォルトの名無しさん:2012/04/17(火) 22:57:13.88
戻り値はconstにする派ってのもいたと思う
Effective C++に書いてあるけど、正直やりすぎだと思う
597デフォルトの名無しさん:2012/04/17(火) 23:04:48.95
レスありがとう
…やっぱり、頭が const TYPE の場合はあまり意味なさそうな感じですか?
恐らくコスト面でも無視できるような違いしかないってことですよね。
実際にもあまり使わないという認識でいいのかな

そういえば、 const TYPE&の存在がありましたね…。
const TYPE& はパラメーター(参照)のstd::vectorのアイテム参照とかグローバル変数の配列の参照を返す時とかに有効な気がしますが
intとかfloatみたいな値を返す時とかに積極的に使う理由ってありますか?
598デフォルトの名無しさん:2012/04/17(火) 23:44:43.08
戻り値 const Effective C++ でググれ

>・ 戻り値にconstを使うと、問題のある関数の安全性や効率を改善できる

>例2)
>const Rational operator* (const Ratioanl& lhs, const Rationa& rhs);

>(a * b) = c のようなコードは不正だが、const 指定すればコンパイル時エラーとなる。
>(a * b) = c; これを展開すると、const Rational (a * b) = Rational c となりエラー。

正直こんなのどうでもいいと思うが
599デフォルトの名無しさん:2012/04/18(水) 00:02:43.13
戻り値const派は右辺値参照の登場で窮地に立たされたな
600デフォルトの名無しさん:2012/04/18(水) 00:18:49.01
右辺値参照で何か不都合とかあったっけ?
601デフォルトの名無しさん:2012/04/18(水) 00:21:29.89
右辺値参照とconst絡みで問題なんてないと思うが
教義を貫けない的な話?
602デフォルトの名無しさん:2012/04/18(水) 00:29:13.38
折角右辺値参照を使ってるのに
無駄に複製が発生するようになるからじゃない
603デフォルトの名無しさん:2012/04/18(水) 00:40:30.17
禿の自刃に殉じた使徒の数知れず (;ω;)
604デフォルトの名無しさん:2012/04/18(水) 01:01:44.61
>>598
>・ 戻り値にconstを使うと、問題のある関数の安全性や効率を改善できる
>・ 戻り値にconstを使うと、問題のある関数
>問題のある関数
メイヤーズ氏もついに演算子の多重定義をdisる境地に達したのか
605デフォルトの名無しさん:2012/04/18(水) 01:23:01.73
「定数式が必要です」と言われてしまいました……教えてください。
「sound_effect.h」に次のように書きました。簡略化しています。

#ifndef SOUND_EFFECT_H
#define SOUND_EFFECT_H
extern const int SOUND_EFFECT_MAX;
class CSoundEffect{
public:
CSoundEffect();
~CSoundEffect();
void RaiseFlag(int Num);
void LoadSet(int SoundSet_Num);
void Play();
private:
int File[SOUND_EFFECT_MAX];
int Flag[SOUND_EFFECT_MAX];
};

そして、「sound_effect.cpp」には次のように書きました。各関数の定義ははぶきます。

#include "sound_effect.h"
const int SOUND_EFFECT_MAX = 45;
CSoundEffect SE_Object;

すると、SOUND_EFFECT_MAXが代入済みの整数定数とみなされていないのか、
「構造体または共用体中にサイズが 0 の配列があります」ということになってしまいます。
なお、extern const intではなく#defineを用いるようにすれば、エラーは出なくなります。
ですが、整数定数の定義には#defineではなくconstを使うようにしろと言われてきたので……
606デフォルトの名無しさん:2012/04/18(水) 01:25:49.79
すみません、簡略化時に#endifを削ってしまいました。
「sound_effect.h」の末尾に#endifがあるものとしてお答えください。
607デフォルトの名無しさん:2012/04/18(水) 01:28:02.72
enum { SOUND_EFFECT_MAX = 45 };でいいだろ
608デフォルトの名無しさん:2012/04/18(水) 01:41:50.09
俺ならメンバ変数にstatic const int SOUND_EFFECT_MAX = 45; ってやっちゃうな
externだとリンクの時に初めて値が入るとかでコンパイル時にそういう風に使っちゃいけないんだろう
609デフォルトの名無しさん:2012/04/18(水) 01:57:38.08
どうしてもexternでやりたいなら
sound_effect.h
extern const int SOUND_EFFECT_MAX= 45;

sound_effect.cpp
const int SOUND_EFFECT_MAX;

だな
610デフォルトの名無しさん:2012/04/18(水) 02:20:37.69
クラス定義はマクロじゃないからな。
611デフォルトの名無しさん:2012/04/18(水) 04:44:22.33
const定数のリンケージがC++だと、Cと違ってそのモジュール内だけになるからだったか?
そのルールって、C++は定数式で配列が初期化できるからあるってことかな?
612デフォルトの名無しさん:2012/04/18(水) 05:03:50.99
黙して共用ヘッダの無名空間に収めとけよ
613デフォルトの名無しさん:2012/04/18(水) 07:34:46.83
外部リンケージの const 定数は配列の要素数などには使えない仕様

内部リンケージ(const が付く場合はデフォルト)であっても、
実体定義より前には配列の要素数などには使えない
宣言だけでは無理で、コンパイラは 0 であると仮定してエラー復帰してコンパイルを続けるので
連鎖的に配列が 0 要素だとか変なエラーが出る

class CSoundEffect{
public:
static const int Max = 45;
private:
int File[Max];
int Flag[Max];
};

これでFA
VC6のような化石コンパイラを使わない限りは大丈夫
VC6使うなら enum { MAX = 45 }; で
614デフォルトの名無しさん:2012/04/18(水) 17:50:12.27
皆さんありがとうございます。
おかげさまで解決いたしました。
615デフォルトの名無しさん:2012/04/18(水) 18:50:22.14
こっちにしようかC++11スレにしようか迷ったけどこっちで。
template aliasで下のコードがエラーになる(clangで)のは何故ですか?
barはfooの別名だと思うのですが。

--
template<typename T> struct foo{ /*empty */ };
template<typename T> using bar = foo<T>;
template<template<typename> class T> struct zot { /* empty */ };
void qux( zot<foo> ){ /*empty */ }

void quux( ){
 qux( zot<bar>( )); // ココ
}
616デフォルトの名無しさん:2012/04/18(水) 19:52:51.68
>>586
俺も好き。Java使わさせられるとき
同等の機能が無いから不便で仕方ない。
617デフォルトの名無しさん:2012/04/18(水) 19:54:39.53
>>615
未対応だからじゃね
618デフォルトの名無しさん:2012/04/18(水) 20:32:59.12
zot に bar を渡すときに foo のインスタンス化を要求するからだろ
619デフォルトの名無しさん:2012/04/18(水) 21:33:36.47
fooのインスタンス化は出来るんじゃね?
alias使わずqux(zot<foo>());だけならideoneでも通るし
620デフォルトの名無しさん:2012/04/18(水) 23:47:55.07
C++規格素人だが>615はコンパイラの常識的挙動に照らしておかしくねえ?
template<typename T> using bar = foo<T>;
でbarを本当にfoo<T>の別名として使ってインスタンス化の片棒を担がせるには
Tの型を明示的に与えるか、型推論できるような書き方であらねばコンパイラ困っちゃう

、希ガス
621デフォルトの名無しさん:2012/04/19(木) 00:15:19.40
すわなち、(省略されている型パラメータUを補完したとして)
 template<typename T> struct foo{ /*empty */ };
のTはfooの自由変数だが、
 template<template<typename U> class T> struct zot { /* empty */ };
において、 U,Tは束縛変数の1, 2であって、テンプレートzotの自由変数は
実は( template<typename U> class T )という全体である

で、void qux( zot<foo> ){ /*empty */ } と書いたなら、この実体化では
zotの自由変数( typename<typename U> class T)のTがfooでUがfooの自由変数T、と解釈できる
(で、Uはzotの定義で使われないからUの定義が無くとも実体化できる。)

一方、qux( zot<bar>() )と書いたなら、barをfoo<T>の別名と解釈するときにTの定義が要るから、
上の話で言うUの定義が必要、という違いがある

、、多分、、
622デフォルトの名無しさん:2012/04/19(木) 00:28:33.86
いま思いついたが>621説を検証するには、>615のコードの3行目を
 template<template<typename U> class T> struct zot { U x; };
に変更したときに4行目の
 void qux( zot<foo> ) { /*empty*/ }
がエラーになるか確かめればある意味一応検証になる
エラーにならなければ>621説は反証される
623デフォルトの名無しさん:2012/04/19(木) 00:52:23.75
struct void std::wstring any();
return 3;
624デフォルトの名無しさん:2012/04/19(木) 01:32:56.73
エイリアステンプレートはテンプレートとしては元のテンプレートと別物扱いってことなんだろ

template<class X, class Y> class hoge {};
template<class X> using fuga = hoge<X, X>;

みたいなときはhogeは引数2つのテンプレートでfugaは引数1つのテンプレートとしてふるまうから別物扱いするのが自然だし
625デフォルトの名無しさん:2012/04/19(木) 18:36:57.09
WindowsXP以上,VC2003の環境です。
ある特定のウインドウの位置の変更や、サイズの変更があった場合に
通知を受け取るにはどうすればよいでしょうか?
いまは、ループでずっとGetWindowRect()を呼んでいます。
626デフォルトの名無しさん:2012/04/19(木) 18:41:08.73
イベントにWM_SIZEってなかったっけ?
627625:2012/04/19(木) 18:51:46.80
>>626
監視対象が、自分の作ったウインドウ(アプリ)じゃないんですよね。
DLL作ってフックしないといけないんでしょうかね・・・。
628デフォルトの名無しさん:2012/04/19(木) 19:23:52.04
ループ使わないなら基本的にはフックじゃね
vista以降は上位権限のプロセスのメッセージは取れないらしいけど

あと使ったことないけどCreateRemoteThreadっていうので何か出来るかもしれない
629625:2012/04/19(木) 22:53:19.86
とりあえず、新しいプロジェクトでDLLを作って
WM_SIZE,WM_MOVE,WM_MOVINGをフックできるようになりました。
それで、更新された新しいRECTをEXE側に渡したいのですが、
DLLからEXE側の関数を呼ぶにはどのようにすればよいでしょうか?
630デフォルトの名無しさん:2012/04/19(木) 23:59:45.57
.exeの方にdllexportの関数って用意できないっけ?
exeの方のウィンドウハンドルとってきてメッセージでもいいけど
631デフォルトの名無しさん:2012/04/20(金) 00:23:32.12
セキュリティで弾かれるのはハンドルを取得する時だけで合ってた?
違うプロセスのウィンドウハンドルを指定してゴニョゴニョは問題ないっけ?
632デフォルトの名無しさん:2012/04/20(金) 01:16:30.45
ヘンタイ仕様のAPIの話って、ここでして良いの?
633デフォルトの名無しさん:2012/04/20(金) 01:22:36.10
Mayaのプラグイン作ってそんなかでFindWindowしてSendMessageしたりしてるけど特にはじかれはしてないなぁ、Windows7ね。
exeが多重起動してたらどれからとってくるかは知らね、目的は果たせたからあんま調べてない。
634631:2012/04/20(金) 01:25:31.84
あ、ごめん ここC++スレだった。
でもWin32スレに書いてもまともな返答返ってこなさそうだし困ったもんだね。
635631じゃなくて633でした:2012/04/20(金) 01:26:30.15
たびたびごめんなさい。
636デフォルトの名無しさん:2012/04/20(金) 02:11:53.23
Windowsは一度公開API群を再設計したほうがいい
仮想化でやってるのは内部的な整合性を保つ為だろうけど
どうせなら今までの粗雑なAPIはレガシー化させて
整合性のあるAPIとして生まれ変わったほうがいい
現状の#defineだらけのヘッダーやら互換性の為に残されたAPIやらは
一度分離してくれたほうがみんな幸せになれる
637デフォルトの名無しさん:2012/04/20(金) 02:12:40.39
>>636
Win64は随分まともになってるじゃないか
638デフォルトの名無しさん:2012/04/20(金) 02:34:17.39
Win64?
DWORD→DWORD_PTRのことかね
639デフォルトの名無しさん:2012/04/20(金) 02:35:23.12
.netのクラスライブラリ群がネイティブになって
winapiは、なくなるのじゃないの?
640デフォルトの名無しさん:2012/04/20(金) 02:42:01.50
現状では.NetのGUIはwinapiをラップしたものでしかないぞ…
641デフォルトの名無しさん:2012/04/20(金) 03:04:20.32
メッセージとか継ぎはぎ感が否めないよな
642デフォルトの名無しさん:2012/04/20(金) 03:53:34.34
C99対応を前提にして
BOOLもbool型にしとくべきだろうね
643デフォルトの名無しさん:2012/04/20(金) 07:01:04.44
>>636
WinAPI使わなきゃいいじゃん
使わない自由はある
MSだって昔は.Net Frameworkで切り捨てるつもりだったんだし
644デフォルトの名無しさん:2012/04/20(金) 08:40:17.72
だから WinRT を設計したじゃないか
645デフォルトの名無しさん:2012/04/20(金) 10:42:47.33
WPFでGUI APIを一新したかったんだろうけど、普及しなかったな。
646デフォルトの名無しさん:2012/04/20(金) 11:38:25.04
粗雑で素朴なCのAPIでもABI的な意味で需要はあるし手間の点はQtとかのラッパで十分とも言えるし
647デフォルトの名無しさん:2012/04/20(金) 12:15:25.67
Windows8でAPIが近代っぽいのに変わるんじゃなかった?
Win32APIとかのレガシーなのをやっととっかえる気になったと聞いたが
648デフォルトの名無しさん:2012/04/20(金) 16:01:31.74
.netとかwinrtなんてvmじゃ、いつまでたってもwinapiは撲滅させられない
649デフォルトの名無しさん:2012/04/20(金) 16:21:37.49
俺もWinRTには期待してた
ふたを開ければ機能限定版のWin32APIラッパだった
Windowsにフタをしてやりたくなった
650デフォルトの名無しさん:2012/04/20(金) 16:59:12.08
クラスについて質問です
クラス内にメンバ変数しかなかったら
newする度に変数の分だけメモリを消費するだろうと推測できるのですが
例えば、メンバ変数は2〜3個でも、メンバ関数が100個くらいある場合には
newする度にメモリの消費量が半端ない感じになってしまったりしますか?
クラスのメモリを確保した時の挙動がちょっと気になってしまいまして
詳しい方いらっしゃったら教えてくださいまし
651デフォルトの名無しさん:2012/04/20(金) 17:12:53.29
>>650
こうかな??
ttp://ideone.com/8d2zK

クラスのメンバ関数は普通の関数にthisを食わせる暗黙のパラメータがあるもんだと思ってもらえればイイと思うお。
だから、関数のインスタンスは、一個でいいし、最適化すればクラスに内包してる必要はないと思う。
ちなみに、テンプレート関数にするとちょっと事情が変わってくる。
652デフォルトの名無しさん:2012/04/20(金) 21:02:11.61
template<typename T> class boo
{
friend class T;
};

こんな具合にテンプレート引数をフレンドクラスにしたいのですが方法教えて下さい。
653デフォルトの名無しさん:2012/04/20(金) 21:39:22.82
クラスのメンバでistream&をもってるんだけど、デフォルトは何で初期化すればいいの?
class A {
istream& is;
A(): is(???) {}
A(istream& is): is(is) {}
};
654デフォルトの名無しさん:2012/04/20(金) 21:41:08.84
悪い事は言わないから参照ではなくてポインタを使いなさい。
655デフォルトの名無しさん:2012/04/20(金) 21:41:11.70
初期化できないのでA()は定義しちゃダメ
656デフォルトの名無しさん:2012/04/20(金) 21:42:03.98
>>653
参照だと色々不便な気がするけど大丈夫なの?
んで、デフォルトコンストラクタをProtectedにするとか・・・。
657デフォルトの名無しさん:2012/04/20(金) 21:46:06.02
すまん、もちろんpublic:を忘れている。
ストリームの終端をA()で表現して、
iter!=A()
的な判定をするんだが、654の根拠は何?
iostreamってあぶなっかしい?
658デフォルトの名無しさん:2012/04/20(金) 21:50:04.32
>>657
いや、参照は初期化時以外に実態を束縛できないのでNULL参照になりやすいからアブネーという話だと思うよ。
659デフォルトの名無しさん:2012/04/20(金) 21:53:19.88
istream&じゃなくてistream_iteratorとか持ったら?
660デフォルトの名無しさん:2012/04/20(金) 21:54:35.39
コンストラクタを別の場所から呼び出すのにthisを使う、次のようなコード(拾ってきたもの)
って規格的にはアリでしょうか?

struct sample_class
{
int value;
sample_class(int i): value(i) {}
sample_class() {
*this = sample_class(10);
}
};
661デフォルトの名無しさん:2012/04/20(金) 21:57:04.04
ありだけどそれぐらいならsample_class() : value(10) { }ってしたほうがいいだろ
662デフォルトの名無しさん:2012/04/20(金) 21:59:04.72
>>658
ふむふむ、あんまそういうのに遭遇したことがないからよくわからんが、
シングルスレッドでワンショットで終わっちゃう(走り続けない)ようなソフトでもヤバイのかね?

>>659
そういう人もったことないけど、やってみるわ。アイディアありがとう。
663デフォルトの名無しさん:2012/04/20(金) 22:02:31.54
>>662
実態が生きてるうちは大丈夫かな。デストラクタ走ったら死亡コース。
664デフォルトの名無しさん:2012/04/20(金) 22:07:11.12
>>663
なるほど。自分が書くような小さいプログラムだと、
mainの最後だけでデストラクタ呼ばれるパターンが多いから、
いつも気にしてないんだよね。
でもこれからは気をつけてみるわ。ありがとう。
665デフォルトの名無しさん:2012/04/20(金) 22:21:45.54
>>652
11ならこれで通る。(gccだと4.7以降)

template<typename T> class boo
{
friend T;
};

98だと直接は無理でメンバ関数をfriendにするしかないかな
http://codepad.org/Ako1qKqh
666デフォルトの名無しさん:2012/04/20(金) 22:37:27.70
さっきのistream_iteratorを使えばいいという話ですが、これが通らない・・・
メッセージが邪悪すぎるから、誰か助けてくれ〜
#include <iostream>
#include <utility>
#include <iterator>
using namespace std;

istream& operator>>(istream& is, pair<int,int>& p) {
is >> p.first >> p.second;
return is;
}
int main()
{
istream_iterator<pair<int,int> > is(cin);
}
667デフォルトの名無しさん:2012/04/20(金) 23:16:13.35
グローバルフックするDLLからEXEに通知を受け取るために、
boost::functionをDLL側に渡して、DLLから呼び出したんですが
デスクトップ、スタートボタン、タスクバーが消えましたww
どうしたらよいでしょうか?
(コンソールアプリや他ライブラリでDLLを使いまわしたいので、
ウインドウメッセージでは受け取りたくないんです)

いまこんな感じです↓
>// EXE側
>boost::function<bool(STRUCT&)> func = &CallbackFunction;
>StartHook(func);

>//DLL側
>boost::function<bool(STRUCT&)> callbackFunc;
>EXPORT BOOL StartHook(boost::function<bool(STRUCT&)> &func)
>{
> callbackFunc=func;
> :
> callbackFunc(struct);
>}
668デフォルトの名無しさん:2012/04/20(金) 23:23:33.48
>>667
そんなことできるわけねーだろアホか
669デフォルトの名無しさん:2012/04/20(金) 23:42:36.38
>>666
あんまりいいサンプルじゃないけどこういうのも有るよ的な。
ttp://ideone.com/qaals


正直、std::cinは使ったこと無いからメチャクチャ大変だった。そして、勉強になった。
670デフォルトの名無しさん:2012/04/20(金) 23:47:36.28
>>669
う〜ん、求めているものではないなぁ。
とりあえず、コンパイルエラーの意味がわからんかったんだが、
それに関して何かコメントない?
671デフォルトの名無しさん:2012/04/20(金) 23:51:02.72
>>670
テンプレートを使った実装を使うときにエラー起こすと意味不明な文字の羅列が出て上級者でもイラッと来るらしい。
で、コンセプトっていう機能が入る予定だったけど、ウヤムヤになって空中分解した。
コンセプトがあればエラーメッセージはもっとシンプルになる予定だったそうな。
672デフォルトの名無しさん:2012/04/20(金) 23:58:11.19
別に空中分解したわけじゃないよ
コンセプトマップをユーザーが定義すべきか自動で定義されるべきかが決まらなかったのでC++11に入らなかっただけ
673650:2012/04/20(金) 23:59:43.85
>>651さん
virtutal属性とかテンプレート関数の有無が鍵になる感じなのですね!
便利なクラスにする為に大量にメンバ関数を作る分には問題ない事が分かったので
安心してクラスを作り込みたいと思います。
ちょっと返信遅れちゃいましてごめんなさい。
どうもありがとうございました!
674デフォルトの名無しさん:2012/04/21(土) 00:00:12.19
すまん。ちょっと誇張した。
675デフォルトの名無しさん:2012/04/21(土) 00:01:13.04
>>674 -> >>672
676デフォルトの名無しさん:2012/04/21(土) 00:03:44.63
677デフォルトの名無しさん:2012/04/21(土) 00:03:57.15
>>671
メタプログラミングとかでエラー出ても、メッセージの雰囲気でけっこうわかるんだが、
stringとiostream関連はいまだに読めないw
678デフォルトの名無しさん:2012/04/21(土) 00:09:21.77
>>666
は神待ちです。
679デフォルトの名無しさん:2012/04/21(土) 00:12:42.02
パンピーで悪かったわね。
680677:2012/04/21(土) 01:11:26.04
すいません、色々調べましたがギブアップです。

EXEからDLLにコールバック関数を登録して、DLL側から構造体を受け取るにはどうすればよいでしょうか?
EXE(またはコンパイラ)が変わってもDLLを修正せずにできる方法でお願いします。
681デフォルトの名無しさん:2012/04/21(土) 01:38:32.64
shared_ptr使えばいけるじゃないの?
682デフォルトの名無しさん:2012/04/21(土) 01:48:01.02
exeが適当なウィンドウを作って
dllがFindWindowでexeが作ったウィンドウを見つけて
そのウィンドウハンドルにWM_COPYDATAで構造体を送り付けたらいい
683677:2012/04/21(土) 01:54:10.77
コンソールアプリや関数だけのライブラリからも呼びたいので、
メッセージは使いたくないんです><

関数ポインタはDLLとEXEでアドレス空間が違うんですかね><

>// EXE側
>
>bool CALLBACK func(STRUCT struct){
> return true;
>}
>
>int main(){
> StartHook((LPVOID)&func);
> :

>// DLL側
>EXPORT BOOL StartHook(LPVOID func) {
> STRUCT data;
> data.dat = 0;
>
> bool (*callback)(STRUCT);
> callback = (bool (*) (STRUCT))func;
> callback(data); // ←この次の行の関数呼び出しでランタイムエラー
>


684デフォルトの名無しさん:2012/04/21(土) 01:57:11.92
共有メモリとか名前付きパイプとか
685677:2012/04/21(土) 03:43:58.56
共有メモリだと、フラグとか値が変わるのを無限ループで監視しないといけないですよね?
それは無駄に重くなるのでやりたくないんですよね。。。
名前付きパイプ調べてみましたが、イベントってのが使えそうな気も・・・。

それと、DLLからEXEの関数呼び出しはなんとなくできました。
EXE側の関数をdllexportして、DLL側からEXE側にGetProcAddress()して関数アドレスを取得して
呼び出せました。これなら新しいEXEを作るときもDLLを変えずに済むかなと思ったのですが、
フックプロシージャからEXE側の関数を呼び出すと、なんかダイアログ出てきてシステムに無理やりDLLをとめられました・・・。
自分のミスなのか、フックプロシージャ内はなにか特別なのか??
686デフォルトの名無しさん:2012/04/21(土) 03:48:34.25
当たり前だろ
フックされたプロセスとフックを仕掛けたプロセスは違うんだから
呼び出せるわけがない
687デフォルトの名無しさん:2012/04/21(土) 03:59:22.71
どうでもいいけどC++関係ねぇ
688デフォルトの名無しさん:2012/04/21(土) 04:01:23.44
そろそろ
http://toro.2ch.net/test/read.cgi/tech/1333095907/
こっちに移るべきだな
689677:2012/04/21(土) 04:04:56.72
>>686
そうなんですか・・・。
EXEと静的リンクしたDLLは同じプロセス空間、
DLLのフックプロシージャの中は別のプロセス空間ということでしょうか?
690デフォルトの名無しさん:2012/04/21(土) 07:05:04.65
>>662
コンストラクターの引数は参照で、
内部ではポインターで保持したら?
691デフォルトの名無しさん:2012/04/21(土) 09:49:36.25
c++ではmallocとfree関数はつかわないんでしょうか?
newとdelete演算子ですか?
692デフォルトの名無しさん:2012/04/21(土) 09:51:40.35
deleteも使わない
693デフォルトの名無しさん:2012/04/21(土) 09:53:15.77
えっそうなのw
横から便乗で質問だけど、コンストラクタ・デストラクタ呼び出したい時はnew deleteなのはわかったけど
その必要がない場合でもnew deleteすべき?
694デフォルトの名無しさん:2012/04/21(土) 09:53:56.00
そんな質問する様なら、1つ良い事を教えてあげる。

混ぜるな危険!
695デフォルトの名無しさん:2012/04/21(土) 10:17:08.33
newは遅いという説が・・・・
696デフォルトの名無しさん:2012/04/21(土) 10:22:17.05
>>695
右辺値参照で改善に期待。
697デフォルトの名無しさん:2012/04/21(土) 10:24:19.29
>>695
placement newでおk
698デフォルトの名無しさん:2012/04/21(土) 10:53:22.07
newの中身は普通はただのmallocだよ
他にはコンストラクタも動かすけど、それはplacement newでも同じ
699デフォルトの名無しさん:2012/04/21(土) 11:41:10.25
>>697
placement newを教えるからにはstd::aligned_storageもだな…。
700デフォルトの名無しさん:2012/04/21(土) 11:42:27.96
そしてoperator new の闇に嵌まって逝く訳ですね
701デフォルトの名無しさん:2012/04/21(土) 13:38:50.23
>>666
istream_iteratorの中からは自分でグローバルに定義したoperator >>が見えない(stdのoperator >>に隠蔽される)からエラーになる。

・解決法の一つ。stdじゃない場所に自分で定義したクラスを介する。

class mypair
{
pair<int, int> p;
public:
mypair() : p() {}
mypair(pair<int, int> const & p1) : p(p1) {}
operator pair<int, int>() const { return p; }

istream & readvalue(istream & is) { return is >> p.first >> p.second; }
};

istream & operator >>(istream & is, mypair & pr)
{
return pr.readvalue(is);
}

int main()
{
istream_iterator< mypair > is(cin);
pair<int, int> p = *is;
}
702デフォルトの名無しさん:2012/04/21(土) 18:01:10.22
>>691
malloc()は使用する必要性がほぼ0になるが
個人的にはrealloc()はしばしばまれに使うべ
std::vector()が使えるならそれに越したことは無いが
703デフォルトの名無しさん:2012/04/21(土) 18:15:42.26
>>702
> しばしばまれ

どっちなんだよ…
704デフォルトの名無しさん:2012/04/21(土) 18:19:38.93
reallocはPOD型(C++11では概念変わったけど)にしか使えないのがねえ
まあ、環境依存でいいなら多少危険でも使えるケースはもうちょい多いと思うが
705デフォルトの名無しさん:2012/04/21(土) 20:25:59.49
>>701
諦めてたのですが、有り難い限りです!
706デフォルトの名無しさん:2012/04/21(土) 23:52:24.21
デフォルトのnewだとサイズsで取った領域をサイズs+1にしたいとき無条件にnewし直ししかないじゃん?
realloc()はヒープ管理のリンクリストに直に触るから、サイズsの既存分を動かさずに済むことがある
std::vector<T>が中で何やってるかは知らんが、案外realloc()を呼んでいるのではないか
707デフォルトの名無しさん:2012/04/21(土) 23:55:39.79
>>706
reserveで出来なかったっけ?
708デフォルトの名無しさん:2012/04/22(日) 00:01:56.82
newのデフォルトの実装は、環境やコンパイラに依存だろ。
reallocとかと混ぜる根性がよくあるな、おまえら。
709デフォルトの名無しさん:2012/04/22(日) 00:02:23.30
>>706
実装によるけど一般的には、vector<T>は要求よりも多めに確保して現在の利用状況をリポートする。
領域確保時は、何だったかな、現在の1.5倍だったかの領域をnewしてコピーするんだったかな。
まー、実装依存だわね。
710デフォルトの名無しさん:2012/04/22(日) 00:09:22.80
>>706
reallocなんで呼ぶわけないだろw
事前確保の容量超えたら新しくnewしてコピー/ムーブだよ

>>709
GCCとMSVCがそれぞれ1.5倍と2倍(どっちがどっちか忘れた)だったはず
711デフォルトの名無しさん:2012/04/22(日) 01:08:33.21
勝手にコピーや元の領域の開放を行わないreallocがあれば
vectorもどきを作るのに使えるのにね・・・
伸ばせるなら伸ばす、伸ばせなければ失敗、
あるいは、新たな領域を確保して、それを返すだけ、という
712デフォルトの名無しさん:2012/04/22(日) 01:14:34.54
>>711
誰がコンストラクタ走らせるの?
そういう用途はプレイスメントnewという機構があるよ。
713デフォルトの名無しさん:2012/04/22(日) 01:15:34.87
>>712
vectorがどういう風に実装されてるか知ってる?
714デフォルトの名無しさん:2012/04/22(日) 01:19:53.01
実装を知らないと使えない、とか、
オブジェクト指向と言うかC++の思想に反するよな。
715デフォルトの名無しさん:2012/04/22(日) 01:23:08.37
>>714
何を言ってるのか意味が分からない
716デフォルトの名無しさん:2012/04/22(日) 01:23:30.27
>>713
詳しくは知らない。
でも、アロケータにメモリ確保を任せて帰ってきたメモリをプレイスメントnewしてるのかねぇ。
オブジェクトをプッシュバックしたら、コピコンかムーブで移譲だよね。
その段階で破棄されるオブジェクトのデストラクタ走るし。

俺はユーザープログラマだからそんな詳しく知らなくても使える。と、言い訳。
717716:2012/04/22(日) 01:25:35.85
アロケータの実装がreallocであることもある可能性は捨て切れない。
718デフォルトの名無しさん:2012/04/22(日) 01:29:43.11
reallocは絶対に使えないのよね
領域が移動する場合に、reallocが勝手に内容をmemcpyするから
ちゃんとしたコピーなりムーブなりが行われない

逆に言えば、この領域移動さえなければ使えると言う事
719716:2012/04/22(日) 01:32:35.49
ほぇ〜。そうなんだ。
アロケータのことはよく知らんのよ。実装する機会もないし。
720デフォルトの名無しさん:2012/04/22(日) 01:36:35.68
newした内容をmemcpyでコピーできないのと同じ事さ
アロケータの知識は正直あまり関係ない
721デフォルトの名無しさん:2012/04/22(日) 01:37:04.38
※ただしPOD型は除く
722716:2012/04/22(日) 01:47:33.69
>>720-721
なるほど。勉強になるよ〜。
723デフォルトの名無しさん:2012/04/22(日) 02:03:06.82
>>722
PODだろうとmalloc、realloc、freeは使うなよ
おいおいnewで確保したか、mallocで確保したか
管理しきれなくなってバグの原因になりかねんから

PODとCの関数で思い出したが、POD型にmemsetでゼロ
初期化するヤツなんなんだろうな。
Type value = {0}; こういう形で十分だろうに。
724デフォルトの名無しさん:2012/04/22(日) 02:04:10.52
Type value = {};
こうだろ
725デフォルトの名無しさん:2012/04/22(日) 02:11:14.53
>>718>>720
それって、要素型Tにコピーコンストラクタが定義されていれば
どうとでもなるんじゃねwwwwwwwwwww

代入と異なりコンストラクタは構築先が何であるかを問わないから
 (そうでない作りにすると普通の構築時に必ずバグって発覚する、)
生のメモリ領域を与えてから構築することができる

、、ハス
726デフォルトの名無しさん:2012/04/22(日) 02:21:38.13
>>723
それ警告出すコンパイラあるから俺は使わない
727デフォルトの名無しさん:2012/04/22(日) 02:23:10.78
>>725
reallocが内部でmemcpyするって言ってんじゃん
コピーコンストラクタもoperator==もガン無視でbitwiseコピーされる
728デフォルトの名無しさん:2012/04/22(日) 02:24:33.50
>>726
Cの仕様で定義されてるんじゃなかったっけ?
俺はそういうふうに習ったけど。

某らんどとかは、変数の初期化処理に警告だしたりするからな。あれは不味いだろうと思う。
729デフォルトの名無しさん:2012/04/22(日) 03:00:04.36
定義はされてるよ
でも、初期化忘れか、意図的な0クリアかを
コンパイラが機械的に判断するのは難しかろう
730デフォルトの名無しさん:2012/04/22(日) 03:01:59.22
>>726
じゃあどうやって初期化してるの?
731デフォルトの名無しさん:2012/04/22(日) 03:19:43.82
>>727
だからプレースメントnewでrealloc()した後にコピーコンストラクタで構築すればいいでしょキイッ
http://www.geocities.jp/ky_webid/cpp/language/036.html

というわけで、realloc()とプレースメントnewの組み合わせで
領域が増えたときのコピーの回数をしばしばたまに減らせることがある
C++ばパフォーマンス命の言語
732デフォルトの名無しさん:2012/04/22(日) 03:33:04.27
それともいっこ、単純にあらかじめ大きめの容量を確保しておくという戦略は
使わないかもしれないオブジェクトについてデフォルトコンストラクタを呼んでしまう欠陥がある
コンストラクタというのは初期化しか仕事しないから高速を要する処理中に極力呼びたくないわけよ
この意味でも常にぎりぎりの領域サイズでrealloc()しつつプレースメントnewというのは
高速処理中にちまちまstd::vec<T>のインスタンスを生成するのに比べたらかなり手堅い
(本当に手堅いのは高速を要する処理開始前に必要なサイズを全部確保しておくことだが)
733デフォルトの名無しさん:2012/04/22(日) 03:49:59.13
命令型言語のPGで新規の領域を不定値のままにして気持ち悪くない奴はカス
なぜなら、命令型言語を選択したPGはその時点でチューリングマシン教の教徒であり、
チューリングマシンは状態の書き換えによって計算を進めるモデルだからだ
そのためのType a = { }だったり(new Typeではく) new Type() 構文だろうノシ
734デフォルトの名無しさん:2012/04/22(日) 04:03:38.84
>プレースメントnewでrealloc()した後にコピーコンストラクタで構築
とか意味が分からないけどとりあえず

>使わないかもしれないオブジェクトについてデフォルトコンストラクタを呼んでしまう
std::vectorもそんな挙動はしないよ?
735デフォルトの名無しさん:2012/04/22(日) 04:39:50.99
>>734
>std::vectorもそんな挙動はしないよ?
ちょっwwwwごめwwwwwwwwっうぇwwwwVS2010のstd::vector<T>で今調べたらそうだったわwwwwwww
(確保した要素数しかデフォルトコンストラクタが呼ばれた)

>意味が分からない
サソプル イズ ベスト:
struct TypeB {
 int x;
 TypeB() : x(-1) { }
 TypeB(const TypeB& other) { x = other.x + 100; } }; // コピーされたら100足される

void test2() { const int n = 100;
  TypeB* sizableArray = (TypeB*)realloc(0, sizeof(TypeB) * n);
  for (int i = 0; i < n; ++i) {
    TypeB a;
    a.x = i;
    new(sizableArray + i) TypeB(a);   // It's new!
  }
  for (int i = 0; i < n; ++i) cout << "sizableArray[" << i << "]=" << sizableArray[i].x << endl;
}
実行結果は、sizeableArray[0] = 100\c\rsizableArray[1]= 101\c\r...
736デフォルトの名無しさん:2012/04/22(日) 08:46:29.23
語るね〜

終わったら呼んで。
737デフォルトの名無しさん:2012/04/22(日) 13:56:10.85
>>731
bitwiseコピーした後にどうコピコンすんだよ
既にアドレス変わってる上に、初期化元は自分自身だろ
738デフォルトの名無しさん:2012/04/22(日) 14:11:44.62
>>737
>new(sizableArray + i) TypeB(a);   // It's new!
739デフォルトの名無しさん:2012/04/22(日) 14:25:17.62
>>738
a って何だ?
740デフォルトの名無しさん:2012/04/22(日) 14:27:32.56
>>739
アドレスsizableArray + i以外の場所にあるTypeB型のオブジェクト
741デフォルトの名無しさん:2012/04/22(日) 14:29:39.39
元データを論理的に保存しないといけないのに
なんで別のものでコピコンすんの?
742デフォルトの名無しさん:2012/04/22(日) 14:34:26.68
>>741
コピコンで元データが論理的に保存されないとする根拠は?

>735のサンプルにおけるTypeBのコピコンにおいて、仮に100を足すのをやめたら
>738で(スタック上の)aと論理的に同じオブジェクトがアドレスsizableArray + iにできるわけだけど?
743デフォルトの名無しさん:2012/04/22(日) 14:35:49.79
>>742
そもそも、realloc したら元データが元の場所から無くなるんだよ
744デフォルトの名無しさん:2012/04/22(日) 14:41:54.04
というか、>>735 読んでなかったが、今話してる事じゃねえよこれ
vectorの伸張の話してんだぞ?
745デフォルトの名無しさん:2012/04/22(日) 14:46:30.01
>>743
ああスマン、それはそうね
p1がTypeBのコピー元配列srcArrayを指しているとして、
 TypeB* p2 = realloc(p1, sizeof(TypeB) * n)
の実行後、p2 != p1でありなおかつsrcArrayの要素がsrcArray内の他要素のアドレスに依存するならそうね

しかし>702以降の流れはstd::vector<T>との比較という文脈なのを思い出してホスイ、
Tにそのような型が許されるだろうか?
746デフォルトの名無しさん:2012/04/22(日) 14:56:54.97
>>711からの流れだと思ってたのだがまあいいや
747デフォルトの名無しさん:2012/04/22(日) 18:51:11.01
>>731
意味が解らん。reallocで1度コピーreplacement newでもう一度初期化。
処理が遅くなるだけだろ何のメリットが有るんだ?
748デフォルトの名無しさん:2012/04/22(日) 18:53:19.14
>>733
命令型ってbashとかzshだろ
メモリ確保は自動で行われるから
確保も開放も意識する必要は無い
749デフォルトの名無しさん:2012/04/22(日) 18:54:29.33
あれだけruby厨だったuy( >>735 )がC++に手を出すようになったか
750デフォルトの名無しさん:2012/04/22(日) 19:00:12.55
>>735
その内容ならmallocでいいだろ
751デフォルトの名無しさん:2012/04/22(日) 19:04:47.26
>>730
memset か std::fill に決まってるジャン(std::fill_n は警告出る事あるのでやはり使わない)
= { 0 } は可読性に劣るとも思うしね
初期化忘れか意図的な 0 クリアかが
コメント残さないと確実に伝えられないから
最初の 0 がある意味マジックナンバーじみているのも気持ち悪い
752デフォルトの名無しさん:2012/04/22(日) 19:30:08.71
普通構造体に = { 0 }してたら初期化だと思うがな。
あと組み込み向けのしょぼいコンパイラーだとこっちの方が早いことがある
逆にmemsetの方が早いってのは聞いたことないけどね
753デフォルトの名無しさん:2012/04/22(日) 19:43:36.33
>>751
それ初期化じゃないじゃん。
それに
={};
で初期化し忘れと読み取るアホはおらんよ。
754デフォルトの名無しさん:2012/04/22(日) 20:04:39.00
= { }; は C で使えないよね
755デフォルトの名無しさん:2012/04/22(日) 20:09:06.33
使えないけど、それがどうかしたの?
756デフォルトの名無しさん:2012/04/22(日) 20:13:57.52
知らない人が結構いそうだから使いたくないわ
757デフォルトの名無しさん:2012/04/22(日) 20:24:10.37
>>747
>reallocで1度コピー
領域拡大時であってもrealloc()だとコピーが起きないことがある
縮小時はもちろんほぼ常に起きないことが期待できる

>replacement newでもう一度初期化。
誰も2回も初期化しないわけだが
つかデフォルトのnewは使えば必ずメモリ確保してから初期化するのに対し、
プレースメントnewはそれ自体はメモリ確保しないから、
メモリがすでに確保されている場合はより早いの
ワカル?
758デフォルトの名無しさん:2012/04/22(日) 20:38:05.66
>>757
理解出来てないなら黙ってろ
759デフォルトの名無しさん:2012/04/22(日) 20:38:21.85
>>748
ソウジャナイ
破壊的代入が本質的(それ無しには何事も進まない)のが命令型言語、
非破壊的代入で全て済ますのが関数型言語
前者はチューリングマシン、後者はλ式をそれぞれ数学的基礎とする

一方で書けるアルゴリズムは他方でも書けるという意味で両者の計算能力は等価
ただし得手不得手はもちろん違う
760デフォルトの名無しさん:2012/04/22(日) 20:41:11.32
>>758
どこらへんがおかしいのかkwsk

つかrealloc()が勝手にコピーするとオブジェクト必ず壊れるとか思ってる?
std::vector<T>の要素型として使える型Tについてはそれは心配せんでええ
761デフォルトの名無しさん:2012/04/22(日) 20:50:37.51
>領域拡大時であってもrealloc()だとコピーが起きないことがある
>縮小時はもちろんほぼ常に起きないことが期待できる

どういう理屈なんだ?
762デフォルトの名無しさん:2012/04/22(日) 20:51:25.25
>>759
お前が言ってるのは手続き型だろ
763デフォルトの名無しさん:2012/04/22(日) 20:54:06.90
>>759
関数型は、演算式と制御文を全て関数で記述する事を目的とした言語
破壊的代入が無いというだけだと宣言型とダブるので、
破壊的代入が無い = 関数型というのはおかしい
764デフォルトの名無しさん:2012/04/22(日) 21:03:04.70
>>761
K&Rの終わりぐらいに書いてあるmalloc()の実装例でも読めばおk
サイズs1、s2の領域がこの順で隣接しており、s2が開放されたなら
サイズs1をサイズs1+s2までコピー無しで拡大することができる
(※簡単のため管理用のヘッダサイズは無視)

>>762
関数型言語であってもリストで手続き(順序的な処理)を表わせるから
手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念
Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、
手続き型というのはそれの対義語
765デフォルトの名無しさん:2012/04/22(日) 21:12:41.32
>>763
宣言型というのは、ようわからんが非手続き型っていうのとほぼ同義ジャネ?
破壊的代入無しでチューリングマシンの計算能力と等価な言語、
といえば多分λ式ベースの言語(つまり関数型言語)しかないんじゃないかなあ、、
なお、関数型は、(関数で)新しい関数を作り出すことしかしない故に関数型
766デフォルトの名無しさん:2012/04/22(日) 21:12:47.96
>>764
mallocじゃなくreallocの内部の話なんだけど
実際コピーしない処理系が存在するのか?
gccのreallocはソース公開されてるがコピーしてる
実際どの処理系がしてるんだ?
普通に考えてもmalloc内部の実装に依存するreallocなんてクソだろ
767デフォルトの名無しさん:2012/04/22(日) 21:15:18.80
>>764
>関数型言語であってもリストで手続き(順序的な処理)を表わせるから
>手続き型/非手続き型の区分は命令型/関数型の切り口とは異なる別概念
>Prologみたいに処理の順序が平に書かれない言語を非手続き型といい、
>手続き型というのはそれの対義語

お前だけの常識で語られてもなぁ
768デフォルトの名無しさん:2012/04/22(日) 21:32:45.54
>>766
realloc()をmalloc()と別階層とすべきですかそうですか、、
コピーを生じない処理系の具体例については、
少なくとも下記コードをVS2010で走らせるとp1 == p2なんだけど?
  void* p1 = malloc(1000);
  void* p3 = malloc(1000);
  free(p3);
  void* p2 = realloc(p1, 2000);
  cout << "p1=" << p1 << ", p2=" << p2 << endl;

glibcのソースをよく読みなおすことをお勧めする

>>767
漏れだけの常識がどうかはようわからんが、そうなの?
>764で妥当だと思うがなあ〜
769デフォルトの名無しさん:2012/04/22(日) 21:35:05.31
で、いつまでちんたらちんたら続くんだ?
770デフォルトの名無しさん:2012/04/22(日) 21:36:14.02
>>760
おいおい、オブジェクト領域でreallocなんか使ったら壊れるだろうがw

ポインタ関係が全部おかしくなるわ。
771デフォルトの名無しさん:2012/04/22(日) 21:38:31.10
>>768
サイズ変更が「可能な場合」はコピーされない。不可能な場合はコピーされる。


コピーされる場合はありえるんだが、たまたま特定環境化で動作するから使っていいとかアホの極み。ドシロウト。

仕事でそれ使ってたらリアルで背任でクビになるようにもっていく。
772デフォルトの名無しさん:2012/04/22(日) 21:39:33.64
>>768
そのコードじゃそりゃそうだろ。
つかそのコードはreallocの問題じゃねぇ。言い方悪かも試練が偶然だ。
解放された領域をもう一度使用してるのは意図して書けばできる事だが、
reallocが同じ領域であることを知っててコピー処理を省略してるかどうかは別問題。
773デフォルトの名無しさん:2012/04/22(日) 21:40:57.09
>>770
>ポインタ関係が全部おかしくなるわ。
ポインタを含まないか、ポインタを含んでも指す先が移動対象でないなら
そういうオブジェクトは勝手にコピーされても無問題でしょ?
で、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、それは成立している、というしくみ
774デフォルトの名無しさん:2012/04/22(日) 21:45:00.34
>>771>>772
まあ冷静に
コピーされる場合がありえるし、コピーされる/されないを
realloc()の呼び出し側で制御できないのは承知していますから
ただ、std::vector<T>の要素型として使えるような型Tのオブジェクトなら、
プレースメントnewをうまく使って安全にrealloc()で領域管理できるという話
775デフォルトの名無しさん:2012/04/22(日) 21:54:51.43
マジレスしないでニヨニヨ笑ってる人が絶対いる悪寒
あまりにも不自然すぎる
776デフォルトの名無しさん:2012/04/22(日) 21:56:42.25
>>774
二重コピーされる分realloc使うのが無駄なのは事実だろ
まだmalloc, free, mallocしてreplacemente new呼んだ方がマシだ
777デフォルトの名無しさん:2012/04/22(日) 22:06:36.44
>>776
ちょっと前のレスから気になってたが、replacement newってなんぞね?
また、realloc()の呼び出し1回で同一オブジェクトのコピーが2回起きるみたいな書き方も気になるが、
それっていつどういうシチュで??

もし>738のようなコピーコンストラクタ呼び出しの回数のことを言ってるのなら、
それはrealloc()一回につき同一オブジェクト当たり1回以下にできる
(realloc()がコピーするかしないかや呼び出し下で制御できないが、
 領域の移動があったかどうかは呼び出し元で判定でき、移動しなかったオブジェクトについて呼ぶ必要はないため。)
778デフォルトの名無しさん:2012/04/22(日) 22:08:51.64
その程度の処理が問題になるなら動的確保自体使わなきゃいいだろ。

まずはEffectiveC++でも嫁やザコ
779777:2012/04/22(日) 22:10:35.64
スマン訂正
std::vector<T>の要素型として使えるような型Tのオブジェクトなら、
勝手にコピーされても何もする必要がないから、領域の移動は関係なかったな、、
780デフォルトの名無しさん:2012/04/22(日) 22:14:06.10
>>777
reallocで1回、new( buffer ) Type();で1回、合わせて2回だろ。
781デフォルトの名無しさん:2012/04/22(日) 22:23:58.97
>>773
自分自身をさすポインタをもつ場合、コピーコンストラクタ/operator=を正しく書けばvectorに入れられるが、メモリコピーでは正しく処理できない。
782デフォルトの名無しさん:2012/04/22(日) 22:34:14.86
>>780
普通そうはならないべ

サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。)
運が悪ければ、領域の移動を要し、サイズs1の部分のみコピーされる(コピー1回)。
ここには今の想定だと構築済みオブジェクトが入っているが、コピー安全なオブジェクトなのでそれ以外なにもしなくていい。つまり、コピーはオブジェクト毎に高々1回。

で、new(p) Type(); が必要なのは、新規に確保されたサイズs2の領域だけ。よって、2回コピーされるオブジェクトは生じない。

なお、細かいことを言えば、new(p) Type()はアドレスpについてType型のデフォルトコンストラクタを呼び出すだけなのでコピーではない。
また、Typeのデフォルトコンストラクタが全フィールドを確実に初期化する保証があるなら
new(p) Type(); と書くより new(p) Type; の方がよろしい。(0 fillが省略されるから早くなる。いつの規格からかは知らん。)

>>781
ああすまん、それはそうね。
783デフォルトの名無しさん:2012/04/22(日) 22:41:23.02
>>782
>サイズs1の領域が確保済みで、realloc()でそのサイズをs1+s2に拡大する場合、効率的な実装なら、まず>764(の前半)のようなケースでは実質コピー0回。(空き領域リンクリストの繋ぎ替えが起きるだけ。)

この前提が間違ってるって何度も指摘されてるだろ
784デフォルトの名無しさん:2012/04/22(日) 22:45:14.75
>>782
手間が増えるだけでreallocするメリットねぇじゃねぇか
785デフォルトの名無しさん:2012/04/22(日) 22:45:21.40
>>783
>何度も指摘
kwsk
すくなくとも、(たまたまかどうかはともかくとして)realloc()前後で領域が移動しなかった実例が>768にあるわけだが
これって呼び出し前後でアドレスが変わらない部分についてもrealloc()は律儀にコピーしてるってことなの??
>738おすすめのヒープメモリ管理方式を聞いてみたい気がするカモメ、
786デフォルトの名無しさん:2012/04/22(日) 22:49:16.76
>>785
ことなの?じゃなくコールスタック追いかけるか
逆アセしてみろよ。memcpy呼ばれてるだろ
787デフォルトの名無しさん:2012/04/22(日) 23:06:31.08
>>786
VS2010のデバッグモードでmemcpy()にブレークポイントしかけて見て見たが、
>768のコードにおける4行目
void* p2 = realloc(p1, 2000);
の呼び出し中のmemcpy(src, dst, count)の呼び出し回数は3回、ただしcountはどれも2だったべ
これはリンクリストか何かのコピーじゃねーの?
(>783の指摘どおりだとしたら1000バイト級のmemcpy()が起きないとおかしいが)

で、仮に万が一>783の指摘が正しかったとして、2回コピーされる件はどうなったのよさ?
主張を取り下げて>782で納得?
788デフォルトの名無しさん:2012/04/22(日) 23:09:34.08
不毛だ
789デフォルトの名無しさん:2012/04/22(日) 23:27:27.52
>>787
2回コピーは俺だが。新しい領域のみコンストラクターの結果を
コピーするんならたしかにコピーは1回だな。そこは納得するよ。
790デフォルトの名無しさん:2012/04/22(日) 23:45:41.19
>>787
http://codepad.org/tlYgmcrc
そもそも、同じアドレスだからと言って一旦解放された領域に
同じ値が入ってるとも限らんからな
このコードVSにコピペして実行してみ
791デフォルトの名無しさん:2012/04/23(月) 01:13:06.56
>>790
ちょっwwwwwwおまwwwwwwwwww
例示のコードはrealloc()とは話が違うわけだが
そりゃーfree()で本当に解放してしまった領域には誰に何書かれるかわからんでしょうよ
(別スレッドあり、デバッグビルドのfree()だと丁重に0xccccccccで埋めてくれたりすることあり。
 セキュリティー目的で埋めるライブラリもあるかも試練、)

なんつーか>768のコードの意図が伝わってないようだけど、
K&R式なmalloc()およびrealloc()な実装の下で>768をシングルスレッド状況で走らせると
>782で言うコピー0回な挙動になるんすよ
>768は、その挙動を演出するために、使用中の領域(p1)とは関係ない領域(p3)を一旦malloc()後にfree()してるだけ
p1が指す領域は一貫してfree()されない。
792デフォルトの名無しさん:2012/04/23(月) 01:26:27.20
>>779
vector の要素型に realloc() で発生しうる memcpy() への耐性なんて要求されてないんだが
793デフォルトの名無しさん:2012/04/23(月) 01:43:35.76
>>791
realloc内部でfreeされるがな
794デフォルトの名無しさん:2012/04/23(月) 02:08:56.95
だから、C++ならnewだけを使えよ。
わざわざ危険を犯そうとする冒険者になることは、ない。
795デフォルトの名無しさん:2012/04/23(月) 02:19:24.31
newの使い方よりも
newそのものの速度が問題になる状況って
どんな状況だ?
796デフォルトの名無しさん:2012/04/23(月) 03:05:19.97
もうほっとけよ
797デフォルトの名無しさん:2012/04/23(月) 03:19:14.56
class MyClass{
public:
bool hoge();
}

MyClass instance;

があるとして、

「instance.hoge()」

が与えられたときに、

「MyClass::hoge(),&instance」

を返すようなマクロは作れませんでしょうか?
798デフォルトの名無しさん:2012/04/23(月) 04:24:58.06
メンバ関数ポインタ
799797:2012/04/23(月) 04:25:55.73
なんとか、
「instance.hoge()」
という記述から、メンバ関数ポインタとthisポインタを取得したいんですよね。。。
800デフォルトの名無しさん:2012/04/23(月) 06:50:18.40
「&MyClass::hoge,&instance」が欲しい理由じゃないのか?
801797:2012/04/23(月) 12:43:53.90
これが欲しい理由は、一度&MyClass::hogeと&instanceを保存しておいて、
あとでそのメンバ関数を呼び出したいんです。
使う箇所が多いので、テンプレートとかでなんとかできないかと思いました。
802デフォルトの名無しさん:2012/04/23(月) 12:53:08.14
std::bindとstd::functionでおk
803797:2012/04/23(月) 14:26:18.17
いやそれだと、
bind(&MyClass::hoge,&instance)って呼び出さないといけないじゃないですか。
これをbind(SUPER_MACRO(instance.hoge()))で記述できるようにしたいんです。
804デフォルトの名無しさん:2012/04/23(月) 14:28:35.01
#define SUPER_MACRO(expr) ([] () { expr; })
805デフォルトの名無しさん:2012/04/23(月) 14:49:33.81
メンバポインタの書式が限定的なのが気に入らないわけね
&MyClass::hoge //現状
~~~~~~~~~~~
&instance.hoge //こう言いたいだけ
806デフォルトの名無しさん:2012/04/23(月) 15:03:37.51
>>803
std::function<T ()> hoge = std::bind(&MyClass::hoge,&instance);
hoge();
hoge();
で我慢しなさい
807デフォルトの名無しさん:2012/04/23(月) 16:23:18.63
>>804
[&]な。
808デフォルトの名無しさん:2012/04/23(月) 17:35:05.27
実行時型情報を使う場合は、
型情報の取得や比較などするクラスについてのみ型情報がバイナリに埋め込まれるのでしょうか?
それとも全てのクラスの型情報が埋め込まれるのでしょうか?
809デフォルトの名無しさん:2012/04/23(月) 17:39:22.96
全て
810デフォルトの名無しさん:2012/04/23(月) 18:17:39.44
じゃあ自前でやりますかな。
811デフォルトの名無しさん:2012/04/23(月) 20:57:41.81
>>774
自身内部へのポインタを持ってても
std::vector<T>のTとして使えるだろ常考
812デフォルトの名無しさん:2012/04/23(月) 21:30:23.79
>811
>781
813デフォルトの名無しさん:2012/04/23(月) 23:11:08.24
vectorって

vector<char [1000]>

みたいに配列を型として作ることできないんでしょうか?
814デフォルトの名無しさん:2012/04/23(月) 23:18:38.75
<固定長の配列>の配列ならboost::arrayをvectorに突っ込む。
<可変長の配列>の配列ならvectorをvectorに突っ込む
815デフォルトの名無しさん:2012/04/23(月) 23:20:00.37
配列型は定数なので無理です・3・
816デフォルトの名無しさん:2012/04/23(月) 23:27:38.75
ちっ
無理か
char *にして毎回メモリ確保してぶっこむわ
サンキュー
アディオス!
817デフォルトの名無しさん:2012/04/24(火) 00:07:51.75
>>816
おいアラインメント
818デフォルトの名無しさん:2012/04/24(火) 00:08:13.27
>>816
なんで既に vector を使ってる文脈で自分でメモリ確保・解放しようだなんて考えるの?
819デフォルトの名無しさん:2012/04/24(火) 00:09:51.28
>>816
アラインメントの問題もあるし、自分でnew/delete管理するのは不可能ではないながらも非常に苦労する部分であるし
毎回メモリ確保するならstd::vector<std::vector<element_type>>ってした方が良いと思う。
820デフォルトの名無しさん:2012/04/24(火) 00:12:23.20
boost::array という解答が出てるのに・・・
boost 使うの嫌なら、構造体に配列だけぶっ込んだ奴を使え
821デフォルトの名無しさん:2012/04/24(火) 00:17:35.80
テストしてみたけど、typedefすらできんのだな。ふむ〜。

Tのサイズ示してナンセンスさを醸し出そうとしたけど大失敗!
あれ上手く行ってもポインタ投げてるだけだよな。
822デフォルトの名無しさん:2012/04/24(火) 00:20:04.20
C++でおk
823816:2012/04/24(火) 00:25:57.46
正直アラインメントがよくわかってないっす

boostは使ったことないっす

vector<element_type>ってのもよく知らないっす

自分でnew,deleteすんのもforループでぶん回して開放するだけなんで苦にならないっす
824デフォルトの名無しさん:2012/04/24(火) 00:36:18.71
vector<vector<T>>だと君がnewとdeleteを管理しなくてよくなるよ。
Tはintとかcharとかの汎用表記だと思ってくれ。
825デフォルトの名無しさん:2012/04/24(火) 00:58:17.08
>>823
それで苦にならんということは、おおかたエラー処理まで考慮すると間違ったコードができあがってる。
826デフォルトの名無しさん:2012/04/24(火) 01:00:10.80
マジすか
じゃあ>>824さんがおっしゃった方法ちょっとやってみます
ありがとうございました
827デフォルトの名無しさん:2012/04/24(火) 01:00:19.84
boost使った事がなくてboost::arrayを敬遠しているなら
template<class Type, std::size_t N>
struct wrapped_array{
  typedef Type type;
  static const std::size_t size = N;
  type elements[size];
};
ってして
std::vector<wrapped_array<char, 1000>>
とすればいいよ。

アラインメントは、単にこちらが「汎用ヒープ領域をchar単位で管理する」と思い違いしただけだから
ここではあまり関係ない。

new,deleteをforで回すのは行儀が良くない、というわけではないけど
デストラクタ以外でnew,deleteを回すという行為自体が、その前のプロセスで例外などが起こった場合の
リーク原因になるからスコープ防壁やshared_ptr等を実装する時以外は直接使わない方がいい。
828デフォルトの名無しさん:2012/04/24(火) 01:00:33.67
>>823
まぁとりあえず使ってみなよ
馴染みの方法を取るのはその後でも遅くは無いさ
829デフォルトの名無しさん:2012/04/24(火) 01:02:05.24
>>768

このコードの前に

  void* px = malloc(1000);
  void* py = malloc(1000);
free(px);

これをやるだけでデバッグビルドじゃとおってもリリースじゃとおらねぇダロアホ。しね。
830デフォルトの名無しさん:2012/04/24(火) 01:04:33.72
>>827
難しそうですね
まあなんとかやってみます。

>>828
気になってはいたんで一度挑戦してみましょうか

ありがとうございました!
831デフォルトの名無しさん:2012/04/24(火) 23:27:02.66
>>827
俺へタレでさっぱりなんだが
static const std::size_t size = N;
でstaticつけるのは何で? 付けないと何か問題生じる?
832デフォルトの名無しさん:2012/04/24(火) 23:29:49.24
コンパイル時定数にならないし
直接初期化もできない
というか、実際にstatic消してコンパイルしてみろ
833デフォルトの名無しさん:2012/04/24(火) 23:31:05.67
834デフォルトの名無しさん:2012/04/24(火) 23:38:55.40
iteratorを仮想化してくれるWrapper Libraryってないですかね?
const InputIterator &begin = InputIteratorImplement< std::vector<int>::iterator >( vector.begin() );
こんな感じで。

なにがしたいかというと、仮想関数の引数にiteratorを使いたいのです。
835デフォルトの名無しさん:2012/04/24(火) 23:43:59.56
ないだろうねぇ
836デフォルトの名無しさん:2012/04/25(水) 00:10:25.60
>>832-833
ありがと。でも何でstatic無だとコンパイルできないのか分らん,orz
wrapped_arrayに要素をどうやって入れるのか、どう要素を参照するのかも分らん
837デフォルトの名無しさん:2012/04/25(水) 00:17:20.89
>>836
static無だとタダの書き換えし辛い変数として扱われ
やろうと思えば実行時に書き換えられるから
実行時に書き換えられる値は定数として使えない
838デフォルトの名無しさん:2012/04/25(水) 00:40:08.04
>>837
ありがと。ある程度知識ある奴ならその説明で分るんだろうが
俺、C++がほとんど分ってないからな

要素へのアクセスってCのstructと同じように出来るんだな
839デフォルトの名無しさん:2012/04/25(水) 06:36:23.18
>>838
入門書を読み直せ、まずはそこからだ
840デフォルトの名無しさん:2012/04/25(水) 18:59:13.19
>>838
親父な俺が中級レベルになるのに役立った本を教えるよ。
エキスパートCプログラミング(訳:梅原系)
EffectiveC++(訳:吉川邦夫)
この2冊かな。More EffectiveC++もまぁよかったよ。
841デフォルトの名無しさん:2012/04/25(水) 19:38:27.38
>>835
仮想関数に不特定のiterator渡したいときどうしてます?
842デフォルトの名無しさん:2012/04/25(水) 19:39:52.13
なにいってんだよ、今時そんなんじゃ中級にもなれないよ。
テンプレート完全ガイドが「せいぜい中級」と言われる世界(すでに初級扱い)で
いまさらその2冊は厳しいっすよ。
843デフォルトの名無しさん:2012/04/25(水) 19:45:59.69
仮想関数にしなけりゃいいだけ。
844デフォルトの名無しさん:2012/04/25(水) 19:47:40.31
仮想関数にしないと実行時に実装きりかえられないんですが
845デフォルトの名無しさん:2012/04/25(水) 20:03:41.89
>834
ないね。仮にあったとして(名前Itとして)、
typename std::iterator_traits<It>::difference_typeは何になるというんだい?
846デフォルトの名無しさん:2012/04/25(水) 20:14:56.35
静的にしか出来ないことを除いたサブセットにすれば問題ないんじゃないですか?
値を書き込むだけでしたら、その手の定義は不要でしょうから。
847デフォルトの名無しさん:2012/04/25(水) 20:16:11.62
>>840
入門書読んでEffectiveC++読んでやっと初心者卒業くらいだろ…?
中級っていうと例外安全なテンプレートを自然に書けたり、
ちょっとしたメタプログラミング的な処理を書けたりするレベルじゃないの
848デフォルトの名無しさん:2012/04/25(水) 20:25:02.43
>>846
仮にあったとして、どう扱いたいの?
InputIteratorで何でも受け付けるなら*itはvoid*でも返すの?
自分で必要とするinterface決めて、使う型に応じてアダプタ書いた方がいいんじゃね?
849デフォルトの名無しさん:2012/04/25(水) 20:26:05.05
おまえらは自分はC++何級って思ってるんだ?
初級、中級、上級、神仙人級....
850デフォルトの名無しさん:2012/04/25(水) 20:27:24.02
>>848
やっぱ自作ですよね。
コンテナは未定ですが、入出力する型(wchar_t)は決まってます。
できれば、書き出しだけじゃなく読み込みもしたいんですけどね。
851デフォルトの名無しさん:2012/04/25(水) 20:29:07.03
>>849
ジーパンスニーカーハゲ級
852デフォルトの名無しさん:2012/04/25(水) 20:41:03.87
やっぱ禿が最高ランクの称号だよな
853デフォルトの名無しさん:2012/04/25(水) 20:41:43.16
>850

class base {
virtual void process_one( wchar_t c, context &ctx ) = 0;
public:
template<typename Iter>
/* non-virtual */ void process_iter( Iter from, Iter to ) {
context ctx;
for( ; from != to; ++from ) process_one( *from, ctx );
}
};
あたりでいいだろ。
854840:2012/04/26(木) 00:16:49.07
御幣があったか。「中級になるのに役立った」ってのを正確に言うと、
「初心者ゾーンを抜け出すきっかけになった2冊」であり、その後の別の経験やきっかけで
「中級になった」ということです。
855デフォルトの名無しさん:2012/04/26(木) 00:17:55.74
>>847
そんなもん初級も初級だろ
856デフォルトの名無しさん:2012/04/26(木) 00:52:05.41
>>849
ここは神仙人級の集まりだな
857デフォルトの名無しさん:2012/04/26(木) 01:00:33.37
スキャンラインアルゴリズムの回答すら1月まともな答えを出せない板の住人が神級とな
858デフォルトの名無しさん:2012/04/26(木) 01:08:15.92
こないだ他の場所でスキャンラインのアルゴリズムを即興で考えて講釈たれたんだけど俺の何級?
859デフォルトの名無しさん:2012/04/26(木) 01:13:07.00
そんなこと言われたら
ショッキュウやわ。
860デフォルトの名無しさん:2012/04/26(木) 01:26:04.83
>>858
初級じゃね?ラジオシティぐらいいかないとな。
861デフォルトの名無しさん:2012/04/26(木) 01:35:52.97
>>849
この流れだと、俺はまだまだ初級かな
862デフォルトの名無しさん:2012/04/26(木) 01:39:21.66
>>860
ラジオシティなんてリアルタイムで光源もりもり動かしたいとかでない限り楽勝じゃね?
数レスで人にやり方伝えるとこまでだったらちょっと難易度高いけど。
863デフォルトの名無しさん:2012/04/26(木) 01:47:38.81
>>862
スキャンラインにしても、ラジオシティにしても実装するだけなら
まともに学校行ってる人間ならできるじゃん
C++使ってんだからいかに実用的な速度と再利用性を維持できるかに
答えられなきゃおはなしにならなくね
864デフォルトの名無しさん:2012/04/26(木) 01:59:19.69
スーパーハカーがそろっているようですねwww

次は年収自慢でも始める?
865デフォルトの名無しさん:2012/04/26(木) 02:01:02.82
年収なんざどうでもいい結果で示せ
866デフォルトの名無しさん:2012/04/26(木) 02:08:05.95
>>865
お前からコードうp汁
867デフォルトの名無しさん:2012/04/26(木) 04:48:38.62
うわっ…私の年収(ry
868デフォルトの名無しさん:2012/04/26(木) 06:31:15.12
無職ですが何か?
面接受けただけで働く気がなくなるような企業ばかりだ
869デフォルトの名無しさん:2012/04/28(土) 18:59:36.23
>>865
一度はドロップアウトした清人だからこそおっさんの面白さを見落とさず拾い上げる事ができたし、それを伝える事もできた。
同じ伝えるプロでも、金持ちに生まれてリア充一直線を突っ走ってきたアナウンサーにこの面白さは伝えられないし、
受け手が勉強ばっかりやって来たオタクではやはり理解する事ができない。
必要なのは人生経験という共通の背景。
870デフォルトの名無しさん:2012/04/29(日) 01:12:22.95
人生経験でも挫折の連続じゃいくら経験しても意味がないんじゃね
871デフォルトの名無しさん:2012/04/29(日) 14:11:15.57
struct X {
int& a;
double b,c;
};
みたいなクラスあるいは構造体があったとき、
・メモリの連続性は保証されていますか?
・オフセットを指定する文法はありますか?
Cなら
unsigned offset: 16;
みたいなのがあった気がするんですが。
872デフォルトの名無しさん:2012/04/29(日) 14:16:56.77
>>871
a,b,cの順番で並んでる事は保証されるが、
a,b,cが隙間無く並んでることは保証されない。
オフセットは標準ではなかったんじゃ無かったっけ?
大体の処理系でoffsetofが使えただろうけど。
別の方法としてメンバー変数のポインタを使う方法もある。
int (X::*n); //こんなの
873デフォルトの名無しさん:2012/04/29(日) 14:17:12.61
ビットフィールドのことかね
874デフォルトの名無しさん:2012/04/29(日) 14:22:34.69
>>872
バイナリ出力するときに、そのままの順序で吐き出せるかと思ってましたが、そうなんですか。ならメンバーで
double bc[2];
とかを持っておいて、個別にアクセスしたほうがいいですね。
ありがとうございます。
875デフォルトの名無しさん:2012/04/29(日) 14:23:56.57
>>871
a, b, c の順番は保証されてるけど、間は詰まっているとは限らない
各メンバのオフセットを直接指定する事はできないが、
間の詰まり方を調整する事はコンパイラによっては可能な場合もある(環境依存)
VC++ と g++ では #pragma pack で調整できるのでググれ
ここまでは、C でも同じ

最新規格の C++11 だと alignas を使って
C++11 対応コンパイラ間であれば環境非依存で調整可能
ただし、もちろん C++11 に対応していないコンパイラでは使えない
876デフォルトの名無しさん:2012/04/29(日) 14:24:28.59
>>873
本当は、aを飛ばしてbcだけをバイナリ出力したかったのです。
ビットフィールドが欲しいわけじゃないので、勘違いでした。
877デフォルトの名無しさん:2012/04/29(日) 14:25:02.01
>>874
アライメントというのがあって、それ意識してメンバーを並べてりゃ隙間は開かないよ。
878デフォルトの名無しさん:2012/04/29(日) 14:25:56.92
>>875
おぉ、有益な情報ありがとうございます。
じぶんでググってみますが、特に有用なページとかあれば教えてください。
879デフォルトの名無しさん:2012/04/29(日) 14:27:16.52
>>877
875と矛盾してますが、仕様ですか?
880デフォルトの名無しさん:2012/04/29(日) 14:28:33.03
>>879
横からだけど、template引数に型を突っ込んでアラインメントを得る事自体が
アラインメント適用した後のストレージの後ろに隙間が開く可能性を孕んでいる。
881デフォルトの名無しさん:2012/04/29(日) 14:31:19.65
>>879
#pragma packと似たような環境依存だよ。
基本的同じOSで動くコンパイラーが生成したコードだと
アライメント規則が同じになる。
こっちは、OSに依存するけどコンパイラーに依存しない。
882デフォルトの名無しさん:2012/04/29(日) 14:31:27.35
>>876
bとcだけなら型が同じなので
連続して記述してあれば配列と同じメモリ配置になるよ
offsetof で先頭からのオフセットが取得可能なので
そこから sizeof(double)*2 だけ出力すればいい
まああんまお勧めしないが

b, c を別構造体にして、それを出力した方が素直だと思う
883デフォルトの名無しさん:2012/04/29(日) 14:44:06.16
32bitなら、4の倍数で塊になるようにメンバーを並べればいい。
例えばshort a; int b; short c;だと、aが4の倍の倍数にならないので2バイト穴が開く。
int b; short a; short c; と並べてやれば穴は開かない。
884デフォルトの名無しさん:2012/04/29(日) 14:54:58.15
>>875
pragma pack なんかは char アラインしかされない int とか作れるけど、
alignas じゃそういうのはできないよ。 (7.6.2 p5)
885デフォルトの名無しさん:2012/04/29(日) 15:03:17.87
#include <iostream>
using namespace std;

struct X {
short x; int y; short z;
};

struct Y {
short x,y; int z;
};

int main()
{
cout << sizeof(X) << endl;
cout << sizeof(Y) << endl;
}

こわ〜い(笑
886デフォルトの名無しさん:2012/04/29(日) 15:08:17.56
>>882
> bとcだけなら型が同じなので
> 連続して記述してあれば配列と同じメモリ配置になるよ

そうなるコンパイラが多いのは事実だろうが、何の保証も無い。
887デフォルトの名無しさん:2012/04/29(日) 15:10:48.03
OSもコンパイラーもどっちの依存も完全になくすには、1メンバーずつ書き込むしかないわな
888デフォルトの名無しさん:2012/04/29(日) 15:13:49.74
エンディアンとか考えはじめるとガクブル・・・
C++11でその辺も何とかなったりしないのだろうか。
889 ◆QZaw55cn4c :2012/04/29(日) 15:32:59.76
>>887
それが幸せだと考えています。
890デフォルトの名無しさん:2012/04/29(日) 16:22:48.87
移植性を考えるなら、テキストでやるか1バイトずつやるか、昔からこの2択でFAだろ。
891デフォルトの名無しさん:2012/04/29(日) 20:55:22.47
ローカルで定義された構造体ってstaticメンバ関数はもてるのにstaticメンバ変数はもてないんですかね?
892デフォルトの名無しさん:2012/04/29(日) 21:06:36.09
と、そのまえに関数G内で関数Fを定義って不可能ですか?
一応方法としてG内で構造体Sを作りその中でstaticメンバ関数Fを定義すれば良いみたいですが
このFからGの変数にアクセスする方法はありますか?
893デフォルトの名無しさん:2012/04/29(日) 21:50:35.66
>>891
関数のローカルstatic変数にアクセスできるから。
staticメンバー関数は、static変数を操作するための関数というより
どちらかというと、static関数が属してるクラスのオブジェクトを操作するための関数。
894デフォルトの名無しさん:2012/04/29(日) 21:56:52.46
ホントですね
じゃあと思ってstatic関数を関数内定義しようとしましたがこれは出来ませんね
うーん
895デフォルトの名無しさん:2012/04/29(日) 22:00:55.30
関数内関数はラムダをキャプチャすればできるかも。
896デフォルトの名無しさん:2012/04/29(日) 22:16:23.00
と、言うわけで、できたはできたんだが、C++0xだった。失念してた。。。。
ttp://ideone.com/GSWFY
897デフォルトの名無しさん:2012/04/29(日) 22:29:39.47
仕事でC++11って使ってる?
898896:2012/04/29(日) 22:32:53.75
趣味グラマですの。
899デフォルトの名無しさん:2012/04/29(日) 23:28:16.28
ラムダ式は関数オブジェクト作るだけだからそれでいいなら03でもローカルな関数オブジェクト作ればいんじゃないか
900896:2012/04/29(日) 23:45:52.61
自分は892とは別人ですの。
901デフォルトの名無しさん:2012/04/30(月) 00:20:15.67
>>897
C+11をサポしているコンパイラーってあんまりないんじゃない
VC2010サポートしているのか
902デフォルトの名無しさん:2012/04/30(月) 00:32:42.56
>>901
VC2010だって一部しかサポートしてない
ラムダ式は大丈夫だったけど
903デフォルトの名無しさん:2012/04/30(月) 01:26:02.64
アレでサポートしてるというのか?
904デフォルトの名無しさん:2012/04/30(月) 01:30:19.89
VC11でも限定的サポートだし、この先どうなるんだか。
905デフォルトの名無しさん:2012/04/30(月) 03:07:17.33
98(03)からVC2005まで何年掛かったかを考えれば解るだろ
906デフォルトの名無しさん:2012/04/30(月) 03:31:40.10
今はC++の規格ってどういう動機で決まってるの?
C++の始まりはストラウストラップ先生の「高速で動くシミュレーション用言語が欲しい」という
個人的動機だったと理解しているが
907デフォルトの名無しさん:2012/04/30(月) 03:40:09.30
>>906
使って出てきた問題が修正されたり、あったらいいよねって機能が追加されたり、
多くの環境で必要とされる独自拡張が標準化されたり、広く使われるライブラリが標準化されたり。
908デフォルトの名無しさん:2012/04/30(月) 03:42:54.34
>>906
Boostはレビューしてもらって多数決で採用が決まる。
レビューで、色々文句も出るので改善しないと採用してくれない。
909デフォルトの名無しさん:2012/04/30(月) 10:04:11.32
>>896
ラムダは関数の引数に渡すとき以外は
普通はautoで受けるぜ
910デフォルトの名無しさん:2012/04/30(月) 15:08:21.36
初心者なんだが、
結局C++で具体的に何が出来るのか教えてくれ。
他のところだと「何でも」しか来なくて具体的な例が知りたい。
911デフォルトの名無しさん:2012/04/30(月) 15:10:30.20
>>910
動作させる環境においてプログラムに許されていることなら何でも出来るよ
912デフォルトの名無しさん:2012/04/30(月) 15:10:48.46
参照渡し
913デフォルトの名無しさん:2012/04/30(月) 15:11:25.23
C++から色んなライブラリを扱うことによって何でもできる
C++だけではGUIアプリは作れん
CUIだけ
914デフォルトの名無しさん:2012/04/30(月) 15:13:39.74
>>911
>>913
あり!!!
915デフォルトの名無しさん:2012/04/30(月) 15:14:08.77
>>910
お前Javaスレにも殆ど同じレスしてたろ
916デフォルトの名無しさん:2012/04/30(月) 15:15:37.39
>>915
よくわかったなw
今プログラミングの勉強してていろんなところで聞いてるw
917デフォルトの名無しさん:2012/04/30(月) 15:17:38.13
ジェネリックプログラミング、
まあ比較的簡単な奴ならJavaやC#でもできるが
C++ほど融通が利かない上に実行速度が1/3ぐらいに低くなる
918デフォルトの名無しさん:2012/04/30(月) 16:11:46.43
>>910

PS3とかの3Dを駆使したゲームも作れるし、
OSも作れるし、
組み込み機器のソフトも作れるし、
ネットワーク関連のソフトも作れるし、
スマートフォンのアプリも作れる。

だから誰に聞いても何でも出来るとしか答えがこない。
当然他の言語の方が楽に作れる分野は一杯あるけどな。
C++で出来ないわけじゃない。
919デフォルトの名無しさん:2012/04/30(月) 16:19:56.28
>>918
おぉ!
ありがたい!

だから皆そう言うのかぁ〜
d(゚Д゚ )☆スペシャルサンクス☆( ゚Д゚)b
920デフォルトの名無しさん:2012/04/30(月) 17:41:01.01
俺は趣味グラマーだけど
おまえらは仕事でC++(Cじゃなく)をメインに使っているのか?
921デフォルトの名無しさん:2012/04/30(月) 17:42:55.68
C++メインだよ
でも同僚はみんなろくにC++を知らない
922デフォルトの名無しさん:2012/04/30(月) 18:38:10.73
C++メインの部署で禄にC++知らないのがほとんどって><
923デフォルトの名無しさん:2012/04/30(月) 18:38:56.60
基本Cでちょっと便利そうな昨日をつまんで使うタイプ
924デフォルトの名無しさん:2012/04/30(月) 18:57:39.37
そんなつもりで使っててもmangling やstatic やadl が避けようも無く暴れ始めるのがC++の凄いところ。
925デフォルトの名無しさん:2012/05/01(火) 00:14:53.96
確かにKoenig lookupは気色悪い
でもあれがなければ<<とか>>のオーバーロードが自然に記述出来なかったわけだ
926デフォルトの名無しさん:2012/05/01(火) 00:22:56.15
>>925
演算子なんか全部グローバル名前空間に宣言することにすればよかったんじゃ?
927デフォルトの名無しさん:2012/05/01(火) 00:30:34.15
えっstdを使わないの?ぶつかって仕方ないんじゃね
928デフォルトの名無しさん:2012/05/01(火) 01:22:20.16
同じ引数型で同じ演算子なら意味付けはひとつにして欲しい。
929デフォルトの名無しさん:2012/05/01(火) 01:34:59.50
何を言ってるの?
930デフォルトの名無しさん:2012/05/01(火) 01:55:40.45
ADLで何で困るのか解らん。
using namespace使いまくるとかバカな事してんのか?
using宣言かnamespaceの別名使うくせをつけろよ
931デフォルトの名無しさん:2012/05/01(火) 01:56:30.05
using namespaceは使わないな
std:: とか boost:: と打つのが快感
932デフォルトの名無しさん:2012/05/01(火) 06:06:38.50
namespace hf = hoge::fuga;
とかはよくやる
933デフォルトの名無しさん:2012/05/01(火) 16:11:32.27
自分のクラスを、継承した別のものにキャストすることは出来ますか?
934デフォルトの名無しさん:2012/05/01(火) 16:20:32.41
出直して来い
935デフォルトの名無しさん:2012/05/01(火) 19:07:56.63
>>934
出直してきました
thisに新しいのを代入してしまえばいいですかね?
936デフォルトの名無しさん:2012/05/01(火) 19:12:00.43
親クラスのthisを、派生クラスのthisにキャストできるかと聞きたかったのか?
937デフォルトの名無しさん:2012/05/01(火) 19:16:09.82
>>936
違います。
親クラスの中で、自分自身を派生クラスに置き換えたいんです。
938デフォルトの名無しさん:2012/05/01(火) 19:17:41.27
>>933
できるっていやーできるが、茨の道だしEffective C++にもいろいろ書いてあった気がするが良い?

a. クラスbaseからその派生クラスderivedへのキャスト
 それを行うコピーコンストラクタをderivedに定義すればできる
 ただし、explicitを忘れると、暗黙の型変換でbase→derivedが行われて死ぬ

b. クラスbaseのポインタ(or 参照)からその派生クラスderivedへのポインタ(or 参照)へのキャスト
 キャストで一応はできる
 (1) 速いが自己責任なやり方
  base* p = new derived;
   derived* q = reinterpret_cast<derived*>(&p);
  これは、qを使ってbaseにないフィールドに「ついうっかり」アクセスすると死ぬ
 (2) 遅いが多少安全なやり方 -- dynamic_castを使う。
   baseに仮想関数が1つ以上無いとコンパイルエラー。
   また、正確にderived*かderived&へのキャストでないと例外が発生する
   
939デフォルトの名無しさん:2012/05/01(火) 19:19:29.73
void Base::Function()
{
  dynamic_cast<Delived>(this)->DelivedFunction(); // 派生class上の関数呼び出し
}
これがしたかった訳じゃないのか
940デフォルトの名無しさん:2012/05/01(火) 19:20:59.96
>>935
コンストラクタ以外ではthisへの代入はできない(コンパイルエラー)
コンストラクタでのthisへの代入は、昔の規格だとコンストラクタがメモリ確保する、の意味に取られるんだったと思う
(今の規格でどうなってるかは知らん)
>938のb.あたりでどう?
941デフォルトの名無しさん:2012/05/01(火) 19:21:49.65
>>938
 (1) 速いが自己責任なやり方
多重継承してても死ぬぞ
942デフォルトの名無しさん:2012/05/01(火) 19:25:52.12
(2) 遅いが多少安全なやり方 -- dynamic_castを使う。
コンパイラーによっちゃインライン展開によって動的処理が消える
reinterpret_cast使っても多重継承でアウトになるし、こっちだけにしとけ
943デフォルトの名無しさん:2012/05/01(火) 19:47:31.60
ダイナミックキャストをしても安全なのはそのオブジェクトが真に派生クラスであった場合だけじゃなかったっけ?・3・;
ダイナミックジャスコしたところでそれは変換前と変換後のクラスが派生関係にあるかどうかを調べるだけで(なければヌル)。
944デフォルトの名無しさん:2012/05/01(火) 19:49:58.24
何を危惧しとんのかしらんが、そらそうよ
945デフォルトの名無しさん:2012/05/01(火) 20:25:25.26
自己言及にすれば?
946デフォルトの名無しさん:2012/05/01(火) 20:26:23.39
>>938
> base* p = new derived;
> derived* q = reinterpret_cast<derived*>(&p);
> これは、qを使ってbaseにないフィールドに「ついうっかり」アクセスすると死ぬ

static_cast にしとけば多重継承してても大丈夫だし生成してるのが
derived なら q を derived として扱って何の問題も無い。
947デフォルトの名無しさん:2012/05/01(火) 20:44:08.30
>>946
static_castの存在を忘れてたスマンス;
あと「qを使ってbaseにないフィールドに「ついうっかり」アクセスすると死ぬ」は確かに間違いで、
「pが指す先が本当はderivedでなかったら死ぬ」に訂正
948デフォルトの名無しさん:2012/05/01(火) 21:43:06.20
&p もダメだな。だから static_cast にしとけと。
949デフォルトの名無しさん:2012/05/02(水) 17:11:52.95
モノステートクラスとシングルトンクラスの使い分けってどうしたらいいんだ?
いまいち相違点というかメリット/デメリットが見えてこない。

互いに、アプリレベルでひとつしか実体を持たないし、
初期化するタイミングをユーザーが選択できる。

ポリモーフィズムできるか出来ないかぐらいか?
950デフォルトの名無しさん:2012/05/02(水) 17:54:44.58
モノステートはインスタンスは幾つでも作れるが、状態が一個しか無い
シングルトンはインスタンスが1つだけ作れる
モノステートは1つしか実態を持たないわけじゃなくて、状態が1つしかないだけ

Construct(メモリ確保と初期化)、Destruct(後処理とメモリ開放)を考えるなら
staticなクラスフィールドに実体が存在し続けるモノステートよりシングルトンの方が優秀
だと個人的に思ってる
951デフォルトの名無しさん:2012/05/02(水) 21:25:52.62
 モノステートは、C++独自のメリットとして、
デストラクターとテンプレートの親和性が有る。

 まず、デストラクターだが、モノステートが抱きかかえてる
オブジェクトが死ぬタイミングではなく、モノステートのオブジェクトが
死んだ時点で呼ばせる事が出来る。例えば、関数の呼び出しと
脱出のログをとる場合、関数に1個モノステートのオブジェクトを置いて
おけばいい。他にもデストラクターを使った排他制御にも使える。

 次にテンプレートだが、もともとシングルトンを想定してないテンプレートで
コンストラクターを呼び出す仕様になってる場合、シングルトンは使えない。
見た目が他のクラスと変わらないモノステートであれば、問題なく使用できる。

 基本的に、アドレスが同一である事を求める場合ぐらいしかシングルトンのメリットはない。
FlyWeightでもモノステートで実装できるし、static変数の初期化を利用した
根底クラスの拡張もモノステートでできる。
よほどの事情がなけりゃモノステートにしとけばいいだろ。
952デフォルトの名無しさん:2012/05/03(木) 00:05:39.10
>>951
>モノステートのオブジェクトが
>死んだ時点
モノステートなクラスって、
・それ自体のオブジェクト(インスタンス)は生成されない(コンストラクタ系が全部privateなのでできない)
・抱えてるオブジェクトは(あるとしても)全部static
だから、
 死んだ時点=抱えてるオブジェクトのデストラクタが呼ばれた時点=プログラム終了後の後処理タイミング、
なんじゃ…?
953デフォルトの名無しさん:2012/05/03(木) 00:19:22.33
モノステートの定義によるのかもしれんが、↓ここ式の定義を採用するとして、
http://www.geocities.co.jp/bleis_tift/cpp/singleton.html
シングルトンにできてモノステートにできないこととして、抱えているオブジェクトの遅延生成が挙げられる
抱えているオブジェクトが複数あって、相互に依存性があり、
かつ本体のリンケージ単位が分かれていて初期化順序不定、と言う場合
シングルトン1択(コンストラクタできちんと生成順序を指定して遅延生成する)になる

ただ、個人的にはシングルトンオブジェクトの汎用性(第三者が後にいつ生成する使い方をするかわからない)
を考えると、マルチスレッド状況下での生成も考慮せねばならず、するとメモリバリア関連の検証が必要になり、面倒なのでシングルトン嫌いだが
(そう言った事柄をプログラマが完璧に管理できる状況下なら生成タイミングと回数が管理できるということで、シングルトンでなくても良い。)
954デフォルトの名無しさん:2012/05/03(木) 00:31:20.29
>>953
それは間違い。
というか、一般的に言われるモノステートじゃない。
一般的なのは
名前通り単純に、状態が1つだけって事だけで
http://c2.com/cgi/wiki?MonostatePattern
こういうやつね。
コンストラクタのアクセス修飾子はどーでもいいし
メンバ関数がstaticだろうが非staticだろうが関係ない。
955953:2012/05/03(木) 00:37:43.14
>>954
了解;

そして>953の前段は撤回スマンス;
>953式の(誤った)モノステートが抱えているオブジェクトの初期化順序は、多分宣言した順に行われると思うし
そんな規格の微妙な条項に頼らずに初期化順序を保証したければ、
遅延生成専門のクラスFooを設けてFooのコンストラクタ中で遅延生成することにして、
Fooのオブジェクトをstaticにすれば全く安全に解決できるorz
(むしろ>953式の(誤った)モノステートが抱えるオブジェクトと外のオブジェクトとの初期化順序を気にしたが、
 それも上のようにFooを噛ます方法方法で解決できる。)
956デフォルトの名無しさん:2012/05/03(木) 02:25:12.35
>>953
そのサイトいつまで嘘を吹聴し続ける気なんだろうな
957デフォルトの名無しさん:2012/05/03(木) 04:41:36.28
>>949だが、>>950-956
モノステートとシングルトンのくっきりした違いが分ったよ。
(というか>>953のサイトを質問前に読んでいて、混乱したクチだった)

ありがとう。もう陽も昇る頃だが、よく眠れそうだ。
958デフォルトの名無しさん:2012/05/03(木) 17:23:04.08
今まで#define HOGE nantoka
を使ってきましたがEffectiveC++曰くconst type HOGE = nantoka;を使えトのことだったので
使ってみましたが、これがヘッダファイル内だと複数のcppにincludeされて多重定義エラー
externで回避できますがconst外さないと駄目ですが、そういうものですか?const外れるのが気持ち悪いのですが
959デフォルトの名無しさん:2012/05/03(木) 17:27:12.44
すいませn extern const ができました
960デフォルトの名無しさん:2012/05/03(木) 17:30:18.00
>>958
インクルードガード使えや……
961デフォルトの名無しさん:2012/05/03(木) 17:32:54.69
いやインクルードガードとは話が違う
962デフォルトの名無しさん:2012/05/03(木) 19:37:00.53
>>958
typeが整数型なら、多重定義のエラーにならない。constの特例。
それでエラーになるなら、実はCとしてコンパイルしているのでは?
963デフォルトの名無しさん:2012/05/03(木) 20:43:51.71
>>962
>多重定義のエラーにならない。
えっにわかには信じ難い
VS2008で「const int x = 10;」を同じcppファイル内で2回以上書くと
「error C2370: 'x' : 再定義 ; 異なるストレージ クラスです。」と言われる
>960ではないが、とりあえずは重複インクルードをガードすれば解決するんでないの
964デフォルトの名無しさん:2012/05/03(木) 20:58:55.06
がまん大会開始
965958:2012/05/03(木) 21:00:16.38
同じcppファイル内での話ではなく違う翻訳単位の話です
問題は文字列char*でした
const intは通りました。不思議
966デフォルトの名無しさん:2012/05/03(木) 21:09:16.83
const char* const HOGE = nantoka;
ってやらないと
967デフォルトの名無しさん:2012/05/03(木) 21:10:04.99
>>965
クラス内で
class Hoge{
statyic const char* hoge = "hogehoge";
};
ってやってるんじゃないの? もっと詳細に情報書け
968デフォルトの名無しさん:2012/05/03(木) 21:11:14.02
そもそもコード中に"hoge"とか書いた時点でそれ定数なんだから云々とかは言っちゃいけないゲームなんです?
969デフォルトの名無しさん:2012/05/03(木) 21:14:04.82
>>966
おうふ、それで通りました
いろいろ納得
970デフォルトの名無しさん:2012/05/03(木) 21:15:36.03
>>967
いや>965で意味が通ってるし、>966は正しい
>962の「typeが整数型なら」というのは意味不明
(クラス内のstatic const int x = 10;は確かにintでだけ可能という特例があるが)
971デフォルトの名無しさん:2012/05/04(金) 11:08:00.26
みんな我慢大会好きだな
972962:2012/05/04(金) 23:18:35.03
すまん、ぼけていた。
整数型に限らず、constなやつはextern付けない限りみな内部リンケージだったな。
973デフォルトの名無しさん:2012/05/05(土) 17:06:39.12
>>966
毎度だがマクロでないものを全て大文字で書くな
974デフォルトの名無しさん:2012/05/05(土) 17:54:59.48
975デフォルトの名無しさん:2012/05/05(土) 17:58:41.56
976デフォルトの名無しさん:2012/05/07(月) 17:47:20.54
SLTやBoostを使ったプロジェクトに関して質問です。
メインプログラムを自分、サブプログラム(.libや.dll)を他の人が作る場合、
相互での関数呼び出しの引数にstringやvector<>を使いたい場合は、ライブラリのバージョン合わせればOKですか?
コンパイラのバージョンはもちろん固定で。
(受け渡しはTCHAR使えば安全、というのは分かりますが、毎度変換しててはstring使う意味が薄れてしまう)
977デフォルトの名無しさん:2012/05/07(月) 18:49:02.07
>>976
>TCHAR使えば安全
えっ!?
978976:2012/05/07(月) 18:51:27.81
>>977
あ、TCHARだと環境がUNICODEかどうかでchar/wcharになっちゃいますね。
そこはスルーでお願いします。
979デフォルトの名無しさん:2012/05/07(月) 19:06:36.48
>毎度変換
えっ?
980デフォルトの名無しさん:2012/05/07(月) 19:16:45.77
dllとの境界はC互換にした方がいいと思うが・・・
981デフォルトの名無しさん:2012/05/07(月) 20:06:03.81
>>976
> SLTや
えっ?
982デフォルトの名無しさん:2012/05/07(月) 20:08:59.80
えっ?
983デフォルトの名無しさん:2012/05/07(月) 20:15:45.37
質問の意図や前提をくみ取れない糞質問
が多い。それで回答者が逆質問をしたり
悪口を言ったりする。それを前もって思
い描く力が絶望的に欠如してるに違いない。
スーパーハッカーだけが意図を理解できる。
レアなそういう神が颯爽と登場する予感。
984デフォルトの名無しさん:2012/05/07(月) 20:36:57.19
えっ?
985デフォルトの名無しさん:2012/05/07(月) 20:40:37.89
意味不明な質問するやつは出直してこいよ
以降スルーで
986デフォルトの名無しさん:2012/05/07(月) 21:17:16.90
ポイントカードはお餅でしょうか
987デフォルトの名無しさん:2012/05/07(月) 21:17:30.04
読み取れない方の日本語能力に問題があるだろ

>>976
LIBは問題ないだろうが、DLLは地雷を踏んでも泣かない覚悟があるならどうぞ
988デフォルトの名無しさん:2012/05/07(月) 21:20:03.00
しかし皆分かっててやってるという
989デフォルトの名無しさん:2012/05/07(月) 21:22:34.71
地雷って単語使うやつってオヤジだよね
990デフォルトの名無しさん:2012/05/07(月) 21:24:21.26
最近のトレンドは機雷だよな
991デフォルトの名無しさん:2012/05/07(月) 21:35:56.18
ジライヤ

いやそんなことより次スレ誰か
992デフォルトの名無しさん:2012/05/07(月) 22:51:29.64
ファイティングニンジャw
993デフォルトの名無しさん:2012/05/08(火) 04:14:19.62
うめ
994デフォルトの名無しさん:2012/05/08(火) 04:50:38.69
次スレ建つまで待ってろバカ
995デフォルトの名無しさん:2012/05/08(火) 05:42:48.92
(#゚Д゚) さっさと立てろ ゴルァ!!
996デフォルトの名無しさん:2012/05/08(火) 08:29:59.46
ほい、次スレ。

C++相談室 part95
http://toro.2ch.net/test/read.cgi/tech/1336420524/
997デフォルトの名無しさん:2012/05/08(火) 08:34:23.85
(・3・)ノおつ!
998デフォルトの名無しさん
(#゚Д゚) お疲れ様です ゴルァ!!