C++相談室 part78 ..
[2ch|▼Menu]
662:660
10/03/08 12:15:01
>>661
このようにしたのですが、うまく行きません。。。

template<class vtype>
void Test<vtype>::func( )
{
 cout << "aaa" << endl;
}

template<class vtype>
void Test<Test<vtype> >::func( )
{
 cout << "bbb" << endl;
}


663:デフォルトの名無しさん
10/03/08 12:22:01
>>662
URLリンク(codepad.org)

664:660
10/03/08 12:39:43
>>663
ありがとうございます。
クラスレベルで特殊化してしまうと、メンバ関数が沢山ある場合
同じようなコードが沢山生まれてしまうので
関数部分だけ特殊化できれば、と思ったのですが
クラスのところで特殊化しなきゃダメなのですね。



665:デフォルトの名無しさん
10/03/08 12:40:57
>>664
URLリンク(codepad.org)

666:660
10/03/08 12:52:05
>>665
テンプレートと継承の組み合わせというのは考えられませんでした。
ありがとうございます。


667:デフォルトの名無しさん
10/03/08 13:41:10
>>655-657
サンクスです
キャスト≒複製って知りませんでした
時期標準のソースをチラ見したところ標準もキャストはサポートされてなかったので、uniqueの方はキャスト諦めることにしました

668:デフォルトの名無しさん
10/03/08 15:54:42
構造体のメンバ変数を一括で代入する方法ってないんですか?
例えば構造体Aの変数のメンバ変数を全て0にするとか…

669:デフォルトの名無しさん
10/03/08 16:26:02
struct S { int a, b, c; double x, y, z; static S empty; };
S S::empty = { 0 };

S var;
var = S::empty;

670:デフォルトの名無しさん
10/03/08 17:44:32
サンクス。クラス使わないとダメなんすか?

671:デフォルトの名無しさん
10/03/08 18:03:45
pod作る関数を作ればいい。テンプレートで

672:デフォルトの名無しさん
10/03/08 18:05:33
struct S { int a, b, c; double x, y, z;};
S a={0};
これで事足りるんじゃ

673:デフォルトの名無しさん
10/03/08 18:14:12
>>672 それは代入じゃない。

674:デフォルトの名無しさん
10/03/08 18:17:26
あーざっす

675:デフォルトの名無しさん
10/03/08 18:17:34
初期化だ(キリッ

676:デフォルトの名無しさん
10/03/08 19:48:52
>>659
const_cast<int *>(p)だろ
他のconstが必要なら後で付ければいい
何があかんのですか

677:デフォルトの名無しさん
10/03/08 20:22:05
const const_iterator* it;
const_cast(it)

これはどうなるんだ?
const_iteratorはポインタかもしれないしクラスかもしれない

678:デフォルトの名無しさん
10/03/08 20:35:48
const_iteratorがconst Type*だった場合、
itの型はconst Type *constでconst_castするとconst Type*になる。
そうでない場合、const_castするとconst_iteratorになる。ただそれだけの話。

679:デフォルトの名無しさん
10/03/08 20:43:53
>>676
void const * const * const cpcpc = 0;
void ** pp = const_cast<void**>(cpcpc);
void const ** cpp = const_cast<void const**>(pp); // このcastはどうすんの?


680:デフォルトの名無しさん
10/03/08 20:54:34
>>678
>itの型はconst Type *constでconst_castするとconst Type*になる。
なんでType*じゃないんだ?>>676と矛盾しない?

681:デフォルトの名無しさん
10/03/08 22:11:07
std::complexのconj( )って何でメンバ関数ではなくグローバル関数なのですか?

682:デフォルトの名無しさん
10/03/08 22:15:54
無闇にメンバ関数にするとprivateにアクセス出来てしまうから、
privateにアクセスする必要のない関数は
メンバでもfriendでもない関数にするのが良いって
偉い人が言ってた

683:681
10/03/08 22:28:24
>>682
ありがとうございます。

もし自分がcomplex作ったら、conj( )をメンバ関数にして
privateなデータを変更してしまうように実装しそうなのですが
これは良くないんですかね?

684:デフォルトの名無しさん
10/03/08 22:34:42
そもそも変更することがおかしいんじゃないかい。
メンバ変数にするにしてもconstにするべきだと思う。
共役複素数を求めるだけだよね?

685:デフォルトの名無しさん
10/03/08 22:42:05
むしろその程度の軽い型なら不変型にしちゃった方が

686:681
10/03/08 23:02:53
>>684
イメージ的にはこんな感じです。

myComplex<double> mc0(2,2); // 2+2i
mc0.conj( ); // 2-2i

グローバル関数にするとコピーが発生してしまうので
良くないのかなぁ、と思ったのですが。

687:デフォルトの名無しさん
10/03/08 23:14:08
実測した訳じゃないが、
あまり効果なさそうな気はする。
コードを見やすくしたほうがいいんじゃないだろうか。

688:デフォルトの名無しさん
10/03/08 23:28:29
なんで配列はイニシャライザリストで初期化出来ないんですか?

689:デフォルトの名無しさん
10/03/08 23:50:50
C++0xにご期待ください

690:デフォルトの名無しさん
10/03/09 01:16:28
>>679
const増やすのはstatic_castでもreinterpret_castでも出来る
お好きな方で

691:デフォルトの名無しさん
10/03/09 01:19:23
>>690 キャスト無しで通っちゃうよ。

692:デフォルトの名無しさん
10/03/09 01:28:37
>>676
void f(void const* a[]); // const 一個付け忘れてるけど変更できない外部ライブラリ
void f(void* a[]); // 同上、ただし非 const データを対象とするオーバーロード

// ここから自前のコード
void g(void const* const a[])
{
f(const_cast(a)); // 上のオーバーロードに渡したいのに下のほうにいっちゃう
}

こわくね?

693:デフォルトの名無しさん
10/03/09 02:23:22
まあconst_cast使うなってのが基本だから
それを書きやすくするうえに他のキャストと違う形になる
省略記法なんて認められないと思われる

694:デフォルトの名無しさん
10/03/09 07:04:10
>>690-691
うちのVC++2008EEではconst_castかC style castでないと通らないんだけど、
なんかおかしいのかな。

695:デフォルトの名無しさん
10/03/09 07:21:42
どうせ<>書いてないとか

696:デフォルトの名無しさん
10/03/09 07:26:55
通らない
URLリンク(codepad.org)

697:デフォルトの名無しさん
10/03/09 07:48:53
void ** const cpp = static_cast<void **>(pp);
えっ?

698:デフォルトの名無しさん
10/03/09 07:49:47
>>696
それは、規格の文面によって、明示的に禁止されている。
4.4 Qualification conversions [conv.qual]

なぜできないのかというと、それを用いることによって、const性に穴が生じるから。
規格のサンプルコードを、適当にコメントを補って引用すると、

int main() {
const char c = ’c’;
char* pc;
const char** pcc = &pc; // 仮に、これが許可されているとする
*pcc = &c;// ppcを介して、pcを変更している。
*pc = ’C’; // pcはconstでもないのに、constなはずのcを参照出来ているので、変更できる。
}

つまり、constなppcを介して、非constなpcを変更できてしまうので、
pcが、明示的なキャストもなしに、constなオブジェクトを参照することが可能になってしまう。

699:デフォルトの名無しさん
10/03/09 07:57:03
>>698
規格の参照までしていただいて、ありがとうございます。
参考になります。

ということで、これを踏まえて改めて>>679

700:デフォルトの名無しさん
10/03/09 07:57:31
ubuntu の gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)
環境で例外クラスの実装を見ようと思ったのですが
/usr/include/c++/4.4/stdexcept
に logic_error などの宣言はあるのに実装が書いてありません。
どのファイルを見たら良いでしょうか?

701:デフォルトの名無しさん
10/03/09 08:07:03
const_castの話してるやつはコテ着けるか
婉曲表現と皮肉をやめて直接主張しろ
何人かいて訳が分からない

702:デフォルトの名無しさん
10/03/09 08:40:34
はがす時は全はがしが楽じゃね?ってことが基点となっていると思うので

void const * const * const cpcpc = 0;
void ** pp = const_cast<>(cpcpc); // 全はがし
void const ** cpp = const_cast<void const**>(pp); // つける時は書く
// void const ** cpp = const_cast<void const**>(cpcpc); // 一部はがしのときもこれまで同様書ける

というのを望んでんのかも

703:デフォルトの名無しさん
10/03/09 09:06:33
がんばれ
658 :デフォルトの名無しさん :2010/03/08(月) 07:36:01
const_cast ってconstはずしだから <> の中に型書くの無駄だなぁって思ってしまう。
const int* からconstとったら int* に決まってんじゃん、と。

704:デフォルトの名無しさん
10/03/09 14:09:06
constの話で盛り上ってるからついでに聞きたいんだけど

struct X {
int *p;

void test(int x) const
{
*p = x;
}
};

こう書くとconst指定してるのにオブジェクトの内容が変化してる
これって合法なの?


705:デフォルトの名無しさん
10/03/09 14:14:13
>>704
Xのオブジェクトはpであることを思い出せ。
pはint*型だから「int型の値のあるメモリの位置」を指している。
*p = xは「pの指している先のint型の値に対する副作用」であって「pに対する副作用」ではない。

706:デフォルトの名無しさん
10/03/09 15:34:24
pは宝の地図
*pは宝の中身
Xのメンバはpつまり宝の地図
だからtest(int x) constとは宝の地図を書き換えちゃいけないってこと
*p = xは宝の中身を入れ替えているだけ

707:デフォルトの名無しさん
10/03/09 15:39:05
中々面白い例え方をするな。

708:デフォルトの名無しさん
10/03/09 15:54:36
**pは宝の地図の在り処を書いた地図か。判りやすいね。

709:デフォルトの名無しさん
10/03/09 15:57:01
ゲームのお使いクエストだな。
そのお宝の例えは俺は結構好きだな。

710:デフォルトの名無しさん
10/03/09 16:19:18
へー、いい表現じゃん

711:デフォルトの名無しさん
10/03/09 16:23:11
サンクス
正常な動作だったのね

712:デフォルトの名無しさん
10/03/09 17:43:29
new intは新しく宝を作るが、この式自体は新しく作られた宝のありかを示す地図を返す。
new int*は宝の地図を新しく作りその地図のありかを返す式だが、新しく作られた宝の地図には宝のありかは書いてない。
難しいな。

713:デフォルトの名無しさん
10/03/09 19:38:02
new int*なんてあんの? あるなら知らなかった。

714:デフォルトの名無しさん
10/03/09 19:44:58
型なら何でもnew出来るだろ

715:デフォルトの名無しさん
10/03/09 19:46:35
関数型もできるっけ?
関数ポインタじゃなくて。

716:706
10/03/09 21:01:33
何の気無しに書いたんで、反応あって驚いてる。
>>706は、一番最初にポインタを勉強する時に俺が(たまたま)イメージしたもので、
今にして思うと、地図という「質量を持った物体」でポインタを喩えたのが好都合だった気がする。
たまたまそういうイメージをしたお陰で、ポインタもまた「そういう値」である、って所で
まったく混乱せずに済んだ。>>708が言うように、ポインタのポインタも
「勇者は宝箱を開けた。なんと宝の地図を見つけた!」ということだと考えれば楽だったし。

717:デフォルトの名無しさん
10/03/09 22:24:46
C++は勉強するほど自信がなくなっていくな・・・boostマジキチ

718:デフォルトの名無しさん
10/03/09 23:10:15
>>716
初心者には分かりやすい言い例えだね。
俺もそれ使わせてもらいます。


719:デフォルトの名無しさん
10/03/09 23:24:34
住所とか例えるより絶対わかりやすい。

720:デフォルトの名無しさん
10/03/09 23:30:25
>「勇者は宝箱を開けた。なんと宝の地図を見つけた!」

あるあるw

721:デフォルトの名無しさん
10/03/09 23:38:31
ポインタを宝箱に例えるなら、中身の種類は開ける前から判っているんだが

722:デフォルトの名無しさん
10/03/09 23:38:54
s/宝箱/宝箱の地図/

723:デフォルトの名無しさん
10/03/10 00:06:18
で?

724:デフォルトの名無しさん
10/03/10 00:35:08
ヌルポインタはミミックだな
開けると死ぬ

725:デフォルトの名無しさん
10/03/10 01:44:47
住所にたとえるのと変わらんと思うがね

726:デフォルトの名無しさん
10/03/10 01:46:21
ていうか別に喩えなくても分かるから

727:デフォルトの名無しさん
10/03/10 01:46:56
ミミックは固定ボスだから、地図が読めない奴が初見殺しされるだけだろ

728:デフォルトの名無しさん
10/03/10 04:46:42
minorという変数がプログラム中にありますが、
cstdlibをインクルードしたら以下のようなエラーが出るようになりました。

error: macro "minor" passed 2 arguments, but takes just 1

これは単純に、minorという変数名を使うな、という解釈でよいでしょうか?

729:デフォルトの名無しさん
10/03/10 04:58:04
>>728
どう読んだらそんな解釈になるんだよ。

そのエラーが再現する最小ソースを作ってみれ。

730:728
10/03/10 05:25:53
>>729
言葉足らずでした。

上記のエラーは、
ctdlib の中(もしくはcstdlibがインクルードしているファイルの中)に
引数を1つとるminorというマクロ(?)があるから、
引数が2つある自作クラスのオブジェクト名をminorにしてはいけない
ということでしょうか?

以下ソース

#include <cstdlib>

class Hoge
{
 public:
  Hoge( int i, int j ){ }
};


int main(int argc, char* argv[])
{
 Hoge minor(1,1);

 return 0;
}


731:デフォルトの名無しさん
10/03/10 05:36:58
>>730
別に言葉足らずじゃない。>>729が寝ぼけてるだけ。
環境によってはsys/types.hにminorマクロがあるので使わない方がいい。

732:デフォルトの名無しさん
10/03/10 05:43:19
>>731
ありがとうございます。

733:デフォルトの名無しさん
10/03/10 05:56:50
>>730
手元の Cygwin g++ 4.3.4 では何事もなくコンパイルが通ったよ。

ちなみに >728 の環境(OS、コンパイラ、そのバージョン)は何?

734:デフォルトの名無しさん
10/03/10 06:01:57
>>731
cstdlib のインクルードでユーザーが使える名前がマクロ定義されてるのは
コンパイラのバグ(標準違反)だと言ってしまっていいと思うんだけど、そういう
予防しとかないといけないものなの?どっかの環境での常識?

735:728
10/03/10 06:04:13
>>733
Ubuntu 9.10
gcc version 4.4.1

です。

gcc -v の内容全部貼ると
Using built-in specs.
Target: i486-linux-gnu
Configured with: ../src/configure -v
--with-pkgversion='Ubuntu 4.4.1-4ubuntu9'
--with-bugurl=file:///usr/share/doc/gcc-4.4/README.Bugs
--enable-languages=c,c++,fortran,objc,obj-c++ --prefix=/usr --enable-shared --enable-multiarch
--enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext
--enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.4 --program-suffix=-4.4
--enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc
--enable-targets=all --disable-werror --with-arch-32=i486 --with-tune=generic
--enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu
--target=i486-linux-gnu
Thread model: posix
gcc version 4.4.1 (Ubuntu 4.4.1-4ubuntu9)

736:デフォルトの名無しさん
10/03/10 06:14:04
-std=c++98 とかすれば逃げれたりするんじゃないかなー。
まぁ #undef すりゃいいんだけどね。

737:728
10/03/10 06:35:01
以下のソースコードコンパイルすると

#include <cstdlib>

void minor( int i, int j )
{
}

int main(int argc, char* argv[])
{
 return 0;
}


test.cpp:5:26: error: macro "minor" passed 2 arguments, but takes just 1
test.cpp:5: error: variable or field ‘minor’ declared void
test.cpp:5: warning: extended initializer lists only available with -std=c++0x or -std=gnu++0x

というerrorと、warningが出ます。
>>730のソースコードではwarning出ませんでした。

738:デフォルトの名無しさん
10/03/10 09:54:54
functionってすげいな
ソース眺めるだけで勉強になる

739:デフォルトの名無しさん
10/03/10 17:43:07
struct A;
struct B{A a;};
struct A{int a;};
int main(){return 0;}

前方宣言したら、後で定義してれば
使えると思ってたんですが
これがエラーになります
Bの中をA* aにするとエラーが消えるのですが
その辺に理由があるんでしょうか?

740:デフォルトの名無しさん
10/03/10 17:53:13
ちょっと実験してみたところ、前方宣言って思ったほど強くない?んですね
Aのデータは定義されるまでは全く参照出来ないのか

struct A;
struct B{void f(A *a){}}; //セーフ
//struct B{void f(A& a){}}; //セーフ
//struct B{void f(A a){}}; //アウト
//struct B{void f(A& a){a.a;}}; //アウト
//struct B{void f(A* a){a->a;}}; //アウト
struct A{int a;};
int main(){return 0;}

741:デフォルトの名無しさん
10/03/10 18:01:37
サイズがわかってるかどうかで判断できるよ

742:デフォルトの名無しさん
10/03/10 19:10:29
なるほど、セーフなのはアドレスですもんね
ありがとうございました

743:デフォルトの名無しさん
10/03/10 22:23:35
>>738
しかしそんなソースを仕事で書いたら
同僚に白い目で見られそうだww

744:デフォルトの名無しさん
10/03/10 22:40:04
すみません
vectorのresizeでサイズを大きくした時に
拡張した結果メモリの再配置が起こったとすると
resizeする前のデータはコピーされるのでしょうか?

745:デフォルトの名無しさん
10/03/10 22:42:12
ざれます

746:デフォルトの名無しさん
10/03/10 22:43:10
>>744
URLリンク(www.fides.dti.ne.jp)

747:デフォルトの名無しさん
10/03/10 22:43:18
ありがとうございます><.

748:デフォルトの名無しさん
10/03/11 00:56:34
クラスを使ってプログラミングする場合、main関数はどのように使用すればいいのでしょうか?

749:デフォルトの名無しさん
10/03/11 00:59:17
普通に使用すればいいです

Javaみたいにどっかのクラスのstatic関数にする必要はなし、というか無理

750:デフォルトの名無しさん
10/03/11 01:51:16
オペレータオーバーロードの ->* って、どう定義してどう使うんですか?
ググール先生に聞こうと思ったんだけど記号検索できませんでした

751:デフォルトの名無しさん
10/03/11 01:55:22
URLリンク(homepage2.nifty.com)

752:デフォルトの名無しさん
10/03/11 02:06:36
結合力最強の二項演算子なので
マクロとかで細工するときに便利なこともあります

753:デフォルトの名無しさん
10/03/11 02:24:57
>>751
どうもです
しかしなんだこれって感じですね
ポインタエミュレートのために
(myp_hoge->*(&MyPtr<hoge>::Func))(a, b, c);
といった形で使いたいんですが、定義の仕方が分からないです(->なら簡単なんですが・・・)

>>752
そういう特殊な使い方ってよく思いつくもんですよね

754:デフォルトの名無しさん
10/03/11 03:03:47
>>748
徹底したクラス指向で行くならこの程度のものになる。
int main()
{
 MainClass m;
 return m.main();
}

755:デフォルトの名無しさん
10/03/11 04:20:39
int main()
{
 return MainClass()();
}
徹底するならこうだろーと思った俺はそろそろ寝るべきか

756:デフォルトの名無しさん
10/03/11 04:51:32
operator RESULT(); //用意するだろ普通

757:デフォルトの名無しさん
10/03/11 16:29:37
throwでint投げると問題があるようなことを聞いたのですが、
どんな問題があるんでしょうか?
ポインタでキャッチしてしまうとか?

758:デフォルトの名無しさん
10/03/11 16:33:36
受け取る方はみんなstd::exceptionを継承してて欲しいなーって思ってるから

759:デフォルトの名無しさん
10/03/11 16:44:47
なるほど。よくわかりました。

760:デフォルトの名無しさん
10/03/11 17:01:56
istringstream の putback って何回でも呼んでおk?

761:デフォルトの名無しさん
10/03/11 21:28:31
boost::functionとstd::functionって混在しても問題ありませんか?
それともどちらか一方にすべきでしょうか?

762:デフォルトの名無しさん
10/03/11 21:54:55
混在させたこと無いからわからんけど、大丈夫じゃね?
どっちも最終的にはただの関数オブジェクトになるわけだから
boostのほうにstdのfunctionを代入することも逆もできるはず
名前は名前空間があるからかぶるわけないし

763:デフォルトの名無しさん
10/03/11 22:54:37
ABI互換性は?

764:デフォルトの名無しさん
10/03/11 23:03:33
混在といっても、ひとつのコンパイラでコンパイルするんだからABI関係なくね?


765:デフォルトの名無しさん
10/03/11 23:15:46
namespace boost = std ;

766:デフォルトの名無しさん
10/03/11 23:28:03
ありがとうございます。
今のところはboostが使えるならboostが無難かと
思うのでboostにします。


767:デフォルトの名無しさん
10/03/11 23:34:01
>>766
えぇーーー
普通は逆でしょ
標準で済むなら標準を使うのが筋でしょ

768:デフォルトの名無しさん
10/03/11 23:38:24
>>767 std::function はまだ標準じゃないでしょ。

769:767
10/03/11 23:40:20
>>768
そりゃそうだ
boost と std だけ見て function を見てなかったよ

770:デフォルトの名無しさん
10/03/11 23:48:14
>>766も「今のところは」って言ってるしな。


771:デフォルトの名無しさん
10/03/12 01:27:32
placement newを使わずに、任意のメモリ領域にコンストラクタを呼ぶことは不可能?

772:デフォルトの名無しさん
10/03/12 01:30:56
>>771
何がしたいのかわからないけど、コピーでいいなら std::allocator::construct() とか
std::uninitialized_copy() とかが使えるんじゃない?

773:デフォルトの名無しさん
10/03/12 10:16:48
template <class T> void Caller( T &f ){ f(); }
に対して、
void Callee();
があり、
Caller( Callee ); // これだとコンパイルが通るのに、
Caller( &Callee ); // こっちは通らない
のはなぜですか?

774:デフォルトの名無しさん
10/03/12 10:40:58
URLリンク(codepad.org)
それはポインタだからさ

775:デフォルトの名無しさん
10/03/12 20:32:25
関数の引数に配列の参照を渡したいんですが、どうすればいいですか

776:デフォルトの名無しさん
10/03/12 20:54:16
>>774
サンクスです。
T &fは「関数の参照型」と言えばいいんでしょうか?
また、関数ポインタを呼ぶ際は、
(*f)(); //デリファレンスあり
f();//なし
2通りで呼べますが、これはシンタックスシュガー的なものですか?
どっち使ってもOKですか?

777:デフォルトの名無しさん
10/03/12 20:54:42
template<typename T, size_t N> void func(T (&x)[N])

778:デフォルトの名無しさん
10/03/13 00:39:50
typedef std::deque<int>::iterator iterator;
iterator tekitou;
//...
tekitou == iterator(); //tekitouに代入処理がなかったらtrue
を期待して組んでたら例外が発生してパソコンが爆発したんですけど
tekitouがデフォルトコンストラクタ走ったまま何も触られて無いかどうかを判定する方法はありませんか?

779:デフォルトの名無しさん
10/03/13 00:52:18
>>778
パソコンが爆発するプログラムを作っているんだったら
いますぐやめなさい。

780:デフォルトの名無しさん
10/03/13 00:53:54
パソコンが爆発するプログラムを作っているのではありません。
パソコンが爆発するのを防ぐプログラムを作っているのです。

781:デフォルトの名無しさん
10/03/13 01:15:50
爆発させるプログラムにも実に巧妙なメカニズムがあってだな・・・

782:デフォルトの名無しさん
10/03/13 01:17:30
兎に角、例外が発生してプログラムが正常に動作しないと爆発を防ぐ事ができないのです。
ご教示いただけないでしょうか?

783:デフォルトの名無しさん
10/03/13 01:20:26
判定する方法は無い
ポインタと違ってイテレータにはNULL入れられないからねぇ
int *ptr = 0;

784:デフォルトの名無しさん
10/03/13 01:21:45
本当に爆発するというなら、
本題なんてどーでもよくて、爆発させる方法を知りたい気すらする。

785:デフォルトの名無しさん
10/03/13 01:22:35
bool変数でも使って対処しとけ

786:デフォルトの名無しさん
10/03/13 01:24:23
std::pair<iterator, param>ってしてたけどSTLがクソ過ぎてstd::pair<std::pair<iterator, bool>, param>って書かなきゃいけなくなったわ・・・

787:デフォルトの名無しさん
10/03/13 01:25:48
こういうときは boost::optional だっけ?

788:デフォルトの名無しさん
10/03/13 01:26:47
つtuple

789:デフォルトの名無しさん
10/03/13 01:30:12
end()をNULL代わりにしたらあかんの?

790:デフォルトの名無しさん
10/03/13 01:32:49
今回もそうでしたが、コンテナを特定できないとそれは使えません。

791:デフォルトの名無しさん
10/03/13 01:55:44
じゃあNULL用の適当なコンテナ作ればいいじゃん

792:デフォルトの名無しさん
10/03/13 01:58:30
std::pair<iterator, param>ってしてたけどSTLがクソ過ぎてstd::pair<std::pair<iterator, dummy_container>, param>って書かなきゃいけなくなったわ・・・

793:デフォルトの名無しさん
10/03/13 01:59:08
nil使えよ

794:デフォルトの名無しさん
10/03/13 02:06:15
iteratorがコンテナと関連付けられてるかチェックしたいってことなのかな?
わざわざややこしいことやってるように見えるけど

795:デフォルトの名無しさん
10/03/13 02:43:02
namespace boost {
namespace detail { struct none_helper{}; }
typedef int detail::none_helper::*none_t ;
} // namespace boost
namespace boost {
none_t const none = ((none_t)0) ;
} // namespace boost

このコードはいったい何をしようとしてるわけ?

796:デフォルトの名無しさん
10/03/13 02:55:22
ググった?

797:デフォルトの名無しさん
10/03/13 04:11:26
>>795
他のどんな型からも自動変換されないし、
他のどんな型へも自動変換されないような変数を定義してるんじゃね?


798:デフォルトの名無しさん
10/03/13 06:23:39
>>468といい>>778といい、最近のPCは爆発しすぎだな

799:デフォルトの名無しさん
10/03/13 06:27:14
俺のPCは蒸着するぜ0.05秒で。

800:デフォルトの名無しさん
10/03/13 06:52:58
手荷物どころかそのうち航空貨物での取り扱いも断られる

801:デフォルトの名無しさん
10/03/13 07:31:03
そして単純所持禁止へ

802:デフォルトの名無しさん
10/03/13 07:33:53
コンピュータが爆発するって
昔の映画や漫画によくあったな

803:デフォルトの名無しさん
10/03/13 07:52:27
「映画の中のコンピュータ」って
ジョークがあったな

804:デフォルトの名無しさん
10/03/13 08:20:38
「なお、このPCは自動的に消滅する」

805:デフォルトの名無しさん
10/03/13 10:22:54
>>799
あれってさリュック背負ってたりするとセムシ形状に成ったりするん?

806:デフォルトの名無しさん
10/03/13 12:27:14
>>795
なんだこれ超ムズイじゃねぇか。


807:デフォルトの名無しさん
10/03/13 13:03:28
pointer to memberって使ったことあんましないからわからんけど
ほかのpointer to memberじゃないとキャストできない(void *にreinterしても変換できなかった)から他の型と比較できない
なおかつメンバが空だからnullしか入れるものがない
したがってただひとつの状態を持てるってことかな
C++ってこういう気持ち悪いバッドノウハウ多すぎるよね
すなおに仕様でnil型導入すればいいのに

808:デフォルトの名無しさん
10/03/13 13:26:04
一般的な実装上の都合からいうと、
メンバへのポインターは、単なるオフセットに過ぎない。

809:デフォルトの名無しさん
10/03/13 13:30:01
null_ptrをお待ちください

810:デフォルトの名無しさん
10/03/13 17:15:12
>>807
実装上の都合を言語ユーザに押し付けてる感はあるな

811:デフォルトの名無しさん
10/03/13 19:14:16
>>810


812:デフォルトの名無しさん
10/03/13 19:16:22
ごめん、途中で送信してしまった。

>>810
他の言語はともかく、
余計なオーバーヘッドを嫌うC++なら、こういう制限も許される(むしろ歓迎される?)よね。

813:デフォルトの名無しさん
10/03/13 19:38:24
>>810
型変換については妥当な話だと思うし、 nil の不在は実装上の都合ではないだろうし、
何のことを言ってるの?

814:デフォルトの名無しさん
10/03/13 21:11:09
void Test(int *array) {
// ごにょごにょ(配列の長さについては考えないとする)
}

みたいな関数があったとき、
int array[3] = {0,0,0};
Test(array);
はコンパイルできるのに、
Test({0,0,0});
はコンパイルできない。
配列に付ける名前が不足しちゃうのでなんとか名前を付けずにやりたいんだけど、
良い手段ない?
それともなんでもいいからとりあえず名前を付けざるを得ないんだろうか。

815:デフォルトの名無しさん
10/03/13 21:18:13
名前付けないと可読性下がりそう

816:デフォルトの名無しさん
10/03/13 21:21:19
>>814
C++0x をお待ちください。

名前が不足するとかいうのがよくわからんが、マクロでスコープきったり、必要なら
__LINE__ あたりとくっつけとけばよかったりしない?

C++0x 全部じゃなくても、 gcc みたいに C99 の機能が取り込まれてるコンパイラなら
↓こんなのが使えたり。

void Test(int *array);
#define TEST(...) do { int array[] = __VA_ARGS__; Test(array); } while(0)
void Tests()
{
TEST({1,2,3});
TEST({4,5,6});
TEST({7,8,9});
}

817:デフォルトの名無しさん
10/03/13 21:26:22
可変長引数マクロ関数使えるのか

818:デフォルトの名無しさん
10/03/13 21:26:36
>>814
ヘルパー関数を使って、
std::vector<int> make_vector(int num, ...);
Test(&make_vector(3,0,0,0)[0]);
とか、
Test((int*)"\x00\x00\x00\x00""\x00\x00\x00\x00""\x00\x00\x00\x00""\x00\x00\x00\x00");
などの悪手しか思いつかない。

819:デフォルトの名無しさん
10/03/13 21:26:59
配列リテラルとかLL出身者っぽい要望だなぁ

820:デフォルトの名無しさん
10/03/13 21:31:05
>>816
レスありがとうございます。
> 名前が不足するというのがよくわからん
Testを沢山呼ぶんですよ。

それで、
int array1[3] = {0,0,0};
Test(array1);
int array2[3] = {0,0,1};
Test(array1);
int array3[3] = {0,0,2};
Test(array1);
以下大量に。
(実際は配列の中身はもっとぐしゃぐしゃで、規則性はないデータになる)

__LINE__をつけるというのはいいですね。

>>818
レスありがとうございます。
STL不勉強のためすみませんが今はちょっとよくわかりません。

>>819
はい・・・LL出身です・・・。

とりあえず__LINE__くっつける方法で行きたいと思います。ありがとうございました。

821:デフォルトの名無しさん
10/03/13 21:31:50
>>820
なんかTestの引数が全部array1になっちゃってますが、
2回目はarray2、3回目はarray3です・・・。

822:デフォルトの名無しさん
10/03/13 21:36:44
C99にはズバリの機能(複合リテラル)があるのだが、C++0xに入るとは聞いていない。
Test((int[]){0,0,0});

823:デフォルトの名無しさん
10/03/13 21:37:24
二次元配列にすればいいだけなんじゃない
int arys[100][3];
for(int i=0;i<100;++i){
arys[i][0]=0;
arys[i][1]=0;
arys[i][2]=i;
test(arys[i]);
}

824:デフォルトの名無しさん
10/03/13 21:40:22
>>822
std::initializer_listが入る

825:814
10/03/13 21:41:00
>>823
>>820でちょこっと書きましたが、実際には配列のデータはもっとぐしゃぐしゃで、
必ずしも
arys[i][0]=0;
arys[i][1]=0;
arys[i][2]=i;
となるわけではないのです。
質問のために簡略化しているので・・・すみません。

826:デフォルトの名無しさん
10/03/13 21:44:44
それなら読み込めばいいんでは?
int arys[100][3];
for(int i=0;i<100;++i){
cin >> arys[i][0] >> arys[i][1] >> arys[i][2];
test(arys[i]);
}
これは標準入力だけど、別にファイルからでもいいし

827:814
10/03/13 21:50:09
>>826
そうした方がいいでしょうかね・・・大量のデータをソースコードにべた書きするのは
よくないかなぁと思ったんですが、
データをあまり見られたくないんですよ。
それで、別ファイルにするよりはソースコードに埋め込んだほうがどちらかというと
見られにくいかなぁと思ったので。
別にソースに埋め込んでも見ようとすれば見れるのでなんてことはないんですが。

828:デフォルトの名無しさん
10/03/13 21:54:44
慣れたLLでコードジェネレートしればいいじゃない

829:814
10/03/13 21:57:51
>>828
なるほど、考えてみます。ありがとうございます。

830:デフォルトの名無しさん
10/03/13 21:58:14
>>827
__VA_ARGS__ は使えんのか? >>816 にあるやつ。

831:814
10/03/13 22:02:11
>>830
Visual C++ 2008なので使えると思います。
考えてみます。

832:デフォルトの名無しさん
10/03/13 22:04:48
>>820
int *arrays[] = {
{ 0,0,0 },
{ 0,0,1 },
{ 0,0,2 }
};

みたいなのじゃダメなの?
argv と同じやりかた。


833:デフォルトの名無しさん
10/03/13 22:07:18
>>832 コンパイルしてみてから言おうな。

834:デフォルトの名無しさん
10/03/13 22:14:19
めんどくせw


835:デフォルトの名無しさん
10/03/13 22:19:38
>>816
__LINE__とくっつけたとして、どうやって参照するの?同じ行が前提?

836:デフォルトの名無しさん
10/03/13 22:50:27
>>835
同じ行に書くか、ひとつのマクロ内であれば問題なく使えるでしょ。

この場合は単にスコープ分けるだけでも済みそうだし、
__VA_ARGS__ が使えるなら >816 のやつがいいと思う。

837:デフォルトの名無しさん
10/03/13 22:58:41
つーか規則性の無いグシャグシャなデータにしたのがそもそも間違いだろ。なんで誰も突っ込まないんだよ
データってのは規則正しい形式なのが当たり前で、規則正しいからこそコードを簡潔に記述できるんだよ

struct Recode
{
int num[5]; char str[80];
};

Recode recodes[N] =
{
{〜},
{〜},
};

for(int i = 0; i < N; ++i) Test(recodes[i]);

こんな感じに書くのが基本に忠実な答え
まずはデータ形式から見直そう

838:デフォルトの名無しさん
10/03/13 23:08:15
>>837
int の配列って言ってるだろ。十分なデータ構造じゃないか。
規則性がなくてぐしゃぐしゃなのは配列の中の値だろ。

839:デフォルトの名無しさん
10/03/13 23:20:29
(データ長+データ実体)*nを1次元配列で持つとか

840:デフォルトの名無しさん
10/03/13 23:24:19
質問のために簡略化してるって構造のことじゃなくて値のことだったのか?
だったら二次元配列を使おう、でおしまいだね。いったい何を悩んでるんだろう

841:814
10/03/13 23:52:42
Visual C++ 2008ってC99は未だっぽいようです・・・
つまり複合リテラル>>822も可変長引数マクロ関数>>816も無理のようです。

>>840
構造も、値も、です。

>>814にかいたTestは実際はオブジェクトのコンストラクタなのですが、これの定義は
CTest::CTest(int Id, const char* Name, const char* Species, const char *Sex, int* Hp_max, int* Attack, int* Speed)
: (メンバ初期化リスト省略) {}
と、>>814で挙げました配列は3つ、さらに文字列や整数値が引数にあります。
で、これのインスタンスを5個ほど作る処理を書きたいのです。

多次元配列を用いようとすると、Hp_maxとAttack、Speedをまとめて記述し、IdやName,Speciesなどの値と離れて記述する
ことになります。できればインスタンス毎にまとめておきたいのですが・・・

842:デフォルトの名無しさん
10/03/14 00:07:58
実際にどう記述してるのか分からん

843:814
10/03/14 00:09:58
一応締切?とさせていただきます。
レスを頂いた皆さま、大変参考になりました。ありがとうございました。

844:デフォルトの名無しさん
10/03/14 00:14:23
>>841
じゃあ

struct X {
int Id;
const char* Name;
const char* Species;
const char* Sex;
int Hp_max[N];
int Attack[M];
int Speed[O];
};

X xs[] = {
{1, "a", "b", "c", {1, 2}, {3, 4}, {5, 6, 7}}
};

では?

845:814
10/03/14 00:24:12
>>844
メンバ変数のうち、Id、Name、Hp_max、Attack、Speedは親クラスから継承しているメンバなのです。
親クラスが存在するクラスではそういう書き方はできなかったかと・・・

846:844
10/03/14 00:28:37
>>845
初期化用データの格納用に >>844 の X のような構造体を定義すれば
初期化データをすっきり記述できるんじゃないかってこと

847:デフォルトの名無しさん
10/03/14 00:28:58
データ部分は関係ないだろ

848:デフォルトの名無しさん
10/03/14 00:30:13
>>827
どれくらい見られたくないのかにもよるけど、別ファイルにしてスクランブルかけた方が見られにくいよ

849:デフォルトの名無しさん
10/03/14 00:35:39
>>841
ひでぇ。最初っからそう聞けよ。 >814 みたいにしたせいで無駄なレスがあんなに。

850:デフォルトの名無しさん
10/03/14 00:35:49
コンストラクタを一つ増やせってことじゃない?

851:デフォルトの名無しさん
10/03/14 00:37:51
>>845
CTest::CTest(const X &init) : m_id(init.id), ・・・
{
}

852:814
10/03/14 00:38:12
>>849
すみません。私の聞き方が悪かったせいで、これ以上続けても私が質問したいことを上手く書けるか分かりませんので、
これで終わりにさせてください。
乱暴なようで申し訳ないのですが、以後レスは致しません。

853:デフォルトの名無しさん
10/03/14 00:38:22
warota

854:デフォルトの名無しさん
10/03/14 00:39:42
                 ┌─┐
                 |も.|
                 |う |
                 │来│
                 │ね│
                 │え .|
                 │よ .|
      バカ    ゴルァ  │ !!.│
                 └─┤    プンプン
    ヽ(`Д´)ノ ヽ(`Д´)ノ  (`Д´)ノ    ( `Д)
    | ̄ ̄ ̄|─| ̄ ̄ ̄|─| ̄ ̄ ̄|─□( ヽ┐U
〜 〜  ̄◎ ̄  . ̄◎ ̄   ̄◎ ̄   ◎−>┘◎

855:デフォルトの名無しさん
10/03/14 00:41:22
gccのC99拡張機能を有り難がって使ってんじゃねーぞ
聞く方が混乱するだけだ

856:デフォルトの名無しさん
10/03/14 00:42:56
えっ

857:デフォルトの名無しさん
10/03/14 01:15:29
template <int num_of_args> class hoge
{
void operator () (int a1, int a2, ...);
};

num_of_argsに対応してoperator ()の引数の数を変動させたいのですが、特殊化をジェネレートするほかにいい方法は無いですかね?

858:デフォルトの名無しさん
10/03/14 01:22:48
>>857
「ジェネレート」がコンパイル以外のプロセスを指しているのなら、 Boost.Preprocessor が
いくらかマシな手段となるかもしれない。

859:デフォルトの名無しさん
10/03/14 01:23:52
>>857
これじゃダメっすか

template<int N> class hoge {
void operator()(int a) { BOOST_STATIC_ASSERT(N == 1); }
void operator()(int a, int b) { BOOST_STATIC_ASSERT(N == 2); }
void operator()(int a, int b, int c) { BOOST_STATIC_ASSERT(N == 3); }
};

860:デフォルトの名無しさん
10/03/14 01:26:06
>>857
C++0xを、首を長くして待て。

861:デフォルトの名無しさん
10/03/14 01:28:23
きりんさんになっちゃいそうです><

862:デフォルトの名無しさん
10/03/14 01:38:21
>>857
num_of_argsが要らなくない?無いほうがすっきりしないか?

863:デフォルトの名無しさん
10/03/14 01:55:12
俺もそう思う。
どうせ特殊化で生成するなら、オーバーロードでいいんじゃね?

864:デフォルトの名無しさん
10/03/14 02:07:19
>>858
boostはよく知らないんですが後でちょっと探ってきます

>>589
これは面白いですね
コード生成は避けられんませんが、ちょっとシンプルになりました

>>860
待ちきれません

>>862,863
array<3> a(10, 15, 20);
a(1, 5, 3) = 100;
こんな感じで使おうと思ってるんで、num_of_argsは欲しいです

865:デフォルトの名無しさん
10/03/14 02:10:31
俺も要らないと思うわ

866:デフォルトの名無しさん
10/03/14 02:13:28
なぜ[a,b,c]という演算子がないのかっていう有意義な疑問に帰着するわけね。


867:デフォルトの名無しさん
10/03/14 02:14:53
>>866
x[Index(a, b, c)] で代用できるから

868:デフォルトの名無しさん
10/03/14 02:27:47
1次元の配列が作れる。n次元の配列に[a]演算子を適用するとn+1次元の配列が作れるならば、数学的帰納法で無限の次元の配列が作れることが証明できる。
早い話がvector<vector<vector<int>>>だね。

869:デフォルトの名無しさん
10/03/14 02:39:36
>>860
g++ 4.4ではもう使える。

870:デフォルトの名無しさん
10/03/14 02:40:37
ここ数日の質問って何をしたいのか見えてこないのが多いな

871:デフォルトの名無しさん
10/03/14 03:10:09
c++の文法書ってありますか?
書店に行ってもプログラミングの入門書ばかりで
言語仕様の解説書が見つからなくて困ってる

組み込みやる事になってgcc、GNUARM使う事になったんだが
文法がまるで分からん(K&R〜ANSIの頃のCは随分使ったんだが)

872:デフォルトの名無しさん
10/03/14 03:11:27
仕様書読めばいいじゃない

873:デフォルトの名無しさん
10/03/14 03:13:49
>>871
JIS規格ならJISのサイトや取り扱ってる書店で発注すれば購入できたり無料で見たりできるお!!!!!!

874:デフォルトの名無しさん
10/03/14 03:16:24
>>871 URLリンク(ja.lmgtfy.com)

875:デフォルトの名無しさん
10/03/14 03:19:23
文法がまるでわからないのなら
むしろ入門書のほうがいいんじゃないのかw
ってか組み込みならそんなに難しい文法の知識いらないし、
むしろ環境構築の方が面倒な気がするけどね

876:デフォルトの名無しさん
10/03/14 03:22:54
>>871
単にCの延長でいいなら入門書読めば事足りるはず。
C++らしいコードが書きたいなら
Effective C++とかMore Effective C++でも読んどけば?という感じ。
厳密な文法が知りたければISO/IEC 14882:2003が言語仕様書ということになってるが、
これを読んで特定の目的を達成するコードが書けるとは思えんなあ。

877:デフォルトの名無しさん
10/03/14 03:26:22
まぁ気持ちは分かる
入門書だとオペレーターオーバーロードとかnamespaceとかそんなん吹き飛ばして
いきなりstd::coutとか使い出すし

878:デフォルトの名無しさん
10/03/14 03:30:29
>>877
しかも、その場合、ADLまで絡んでくるしな。

879:デフォルトの名無しさん
10/03/14 03:34:03
俺も昔厳密な仕様が知りたいけど
仕様書とかダルイっていう舐めた態度の時にこの本買った
URLリンク(www.hir-net.com)
>>877
な感じで詰まってるなら入門書と並行してこういう本買ってもいいかもね
最近は色々種類あるだろうし翻訳物もあるだろうから本屋行って選ぶよろし

880:デフォルトの名無しさん
10/03/14 04:04:01
組み込みなら組み込みのスレで尋ねた方がいいと思うぜ
C++の一般論が必ずしも当てはまるとは限らんから

881:デフォルトの名無しさん
10/03/14 12:59:49
>>871
組み込みなら C 使えよ。
お前みたいなのが C++ 使うとバグが増える。

とりあえずヘッダ自動生成とかのツール類で
勉強してからにしろ。


882:デフォルトの名無しさん
10/03/14 13:03:01
デストラクタもないCにいわれてもな


883:デフォルトの名無しさん
10/03/14 13:06:49
>>881
> とりあえずヘッダ自動生成とかのツール類で
> 勉強してからにしろ。
何を言っているんだw

884:デフォルトの名無しさん
10/03/14 13:13:53
というか、強い静的型付けもないCなんかで書いたら、誰でもバグが増えるわ。

885:デフォルトの名無しさん
10/03/14 13:58:08
>>882-884
組み込みは製品になるとスタックダンプとレジスタぐらいしか
なくてアセンブラだけで解析すんの大変なんだぜ。

お前らみたいな糞コードのバグ解析がこっちに
回ってきて迷惑なんだよ。


886:デフォルトの名無しさん
10/03/14 14:04:43
そういうクソを調教するためにMISRA-Cとかがあります

887:デフォルトの名無しさん
10/03/14 14:29:06
>>885
組み込みつったって規模があるだろう
それこそメモリが数kbしかないものもあれば、OSが載っているようなシステムだってある
少し極論じゃないのか

888:デフォルトの名無しさん
10/03/14 14:40:51
Cでバグが減る根拠を挙げてもらおうか

889:デフォルトの名無しさん
10/03/14 14:46:53
誰もそんな事言ってないから

890:デフォルトの名無しさん
10/03/14 18:41:27
 template<typename T>
 void foo(const T& arg){
 
 if(T::hoge_flag){
     func_true(arg);
     }
 else{
     func_false(arg);
     }
 
 return;
 }

この様なコードがありまして、T::hoge_flagは
T型によりコンパイル時に決定されるconst bool型の定数とします。
すなわち T::hoge_flag の真偽によって
func_true(arg);とfunc_false(arg);の一方だけが必ず実行され
他方は必ず実行されないことになります。

こういった場合は、テンプレートメタプログラミングを使って
一方だけのコードが実行バイナリファイルに含まれるようにすべきなのでしょうか。
それともコンパイラの最適化を期待して上記のコードのままでも良いのでしょうか。

よろしくお願い申し上げます。



891:デフォルトの名無しさん
10/03/14 19:09:38
コンパイラの機嫌しだい


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5400日前に更新/218 KB
担当:undef