トップページ⇒tech
1001コメント331KB

C++相談室 part46

■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v2006/01/08(日) 12:15:07
C++に関する質問やら話題やらはこちらへどうぞ。
ただし質問の前にはFAQに一通り目を通してください。
IDE(VC++など)などの使い方の質問はその開発環境のスレに
お願いします。

前スレ
C++相談室 part45
http://pc8.2ch.net/test/read.cgi/tech/1133007604/
0232デフォルトの名無しさん2006/01/21(土) 02:35:46
cout << "((arrint&)p)[1][2] " << ((arrint&)p)[1][2] << endl;
cout << "((arrint&)p)[1][3] " << ((arrint&)p)[1][3] << endl;
cout << "((arrint&)p)[1][4] " << ((arrint&)p)[1][4] << endl;
cout << "((arrint&)p)[0][12] " << ((arrint&)p)[0][12] << endl;
cout << "((arrint&)p)[0][13] " << ((arrint&)p)[0][13] << endl;
cout << "((arrint&)p)[0][14] " << ((arrint&)p)[0][14] << endl;

cout << "reinterpret_cast<arrint&>(p)[1][2] " << reinterpret_cast<arrint&>(p)[1][2] << endl;
cout << "reinterpret_cast<arrint&>(p)[1][3] " << reinterpret_cast<arrint&>(p)[1][3] << endl;
cout << "reinterpret_cast<arrint&>(p)[1][4] " << reinterpret_cast<arrint&>(p)[1][4] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][12] " << reinterpret_cast<arrint&>(p)[0][12] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][13] " << reinterpret_cast<arrint&>(p)[0][13] << endl;
cout << "reinterpret_cast<arrint&>(p)[0][14] " << reinterpret_cast<arrint&>(p)[0][14] << endl;
}
0233デフォルトの名無しさん2006/01/21(土) 02:39:35
>>231
こんなんじゃダメなの?(行数詰めたから見難いけど)
template <typename T> struct array_2d {
    T* data_; int size1_, size2_;
    array_2d(int size1, int size2) : data_(new T[size1 * size2]) , size1_(size1), size2_(size2){}
    ~array_2d() {delete[] data_;}
    struct proxy {
        array_2d* parent_; int offset_;
        proxy(array_2d* parent, int offset) : parent_(parent), offset_(offset) {}
        operator T*() {return parent_->data_ + offset_;}
    };
    proxy operator[](int x) {return proxy(this, size2_ * x);}
};
template <typename T> void assign(T& a) {
    for (int i = 0; i < 2; ++i) for (int j = 0; j < 3; ++j) a[i][j] = 10 * i + j;
}
#include <iostream>
int main() {
    array_2d<int> a(2, 3); assign(a);
    for (int i = 0; i < 6; ++i) std::cout << a.data_[i] << ' ';
    std::cout << std::endl;
    int b[2][3]; assign(b);
    for (int i = 0; i < 6; ++i) std::cout << reinterpret_cast<int*>(b)[i] << ' ';
    std::cout << std::endl;
    return 0;
}
0234デフォルトの名無しさん2006/01/21(土) 02:43:15
>>233
あ、俺は210じゃないっす。ただの通りすがりの暇人ですw

>>229
>ポインタを参照に reinterpret_cast して挙動がおかしいのは当たり前。
あーこれはだめなんですか。未定義の部類になるのかな。じゃあgccとVCで結果が違って当たり前ですね。
0235デフォルトの名無しさん2006/01/21(土) 07:17:46
vtbl内における、各仮想関数ポインタのオフセット位置を得たいのですが、どのように書けばいいのでしょうか?
class X
{
public:
 virtual void func1() {};
 virtual void func2() {};
 virtual void func3() {};
};
のような場合、func1()について0、func2()について4(32ビットシステムの場合)、func3()について8が得られる書き方ですが・・・

あと、インスタンスのVtblのアドレスを得るにはどうしたらよいのでしょうか?
X x;
printf("%X\n", *(void **)&x);
こんな書き方しかないのでしょうか?
0236デフォルトの名無しさん2006/01/21(土) 07:57:42
>>235
処理系依存
確実に取得したいなら自前で仮想関数テーブルをエミュレートするしかない
0237デフォルトの名無しさん2006/01/21(土) 09:02:30
>>235
諦めてメンバへのポインタを普通に使え。
0238デフォルトの名無しさん2006/01/21(土) 14:06:53
>>227
要するに p は配列を指すポインタであるので、
配列を指す参照にキャストしてしまうと、間接参照のレベルが一段ずれてしまう。

配列を指す参照を用いるなら

((int (&) [10][10]) (*p)) [1][2] = 3; が正解
0239デフォルトの名無しさん2006/01/21(土) 20:52:20
キャストを使おうとしている人がほとんどみたいだけど、それって
当然規格はその結果を保証してないよね?
0240デフォルトの名無しさん2006/01/21(土) 23:45:36
えーと、ソースのみにローカルなclassを使うときに、
外部から見えないようにするために、namespace { } を使うのですが、

個人的に.cppにclassを書くので、class内部に実装もがんがん書くし
さらに内部structなんかを持たせる時もある、
なーんて事をしていると、(エディタでソース全体を整形することも多いので)
インデントが深くなってちょっと嫌な感じ。

で、
namespace {
 namespace local {
  class localclass;
 }
}
class local::localclass { ... };
using local::localclass;

などという事を考えたのですが、
これ(無名のnamespaceのさらに内部のスコープだけを明示して使用)って合法ですか?

vc,bcc,gcc等でのコンパイルは問題ないみたいですが。
(未定義のstatic変数のエラーメッセージで確認)
0241デフォルトの名無しさん2006/01/22(日) 00:23:46
>>240
大丈夫だと思います。
0242デフォルトの名無しさん2006/01/22(日) 00:27:58
>240
(質問の意図を思いっきり無視して)
namespaceでインデントしなければいい。
0243デフォルトの名無しさん2006/01/22(日) 00:47:42
ほんとにそれで、大丈夫なんですか?
0244デフォルトの名無しさん2006/01/22(日) 00:51:09
大丈夫だと思います
0245デフォルトの名無しさん2006/01/22(日) 00:54:56
>>241
どもです。

>>242
xyzzyでソース全体を整形すると、勝手にインデントしてしまうのですよ・・・
#includeを使って
"namespace hogehoge {" だけのファイルと
"}" だけのファイルを
先頭と最後に入れてごまかそうとした事も。
0246デフォルトの名無しさん2006/01/22(日) 01:02:58
>>245
> #includeを使って
インデントが深くなるよりもこっちの方が気持ち悪い。
0247デフォルトの名無しさん2006/01/22(日) 01:03:38
狂おしいほどハゲドー
0248デフォルトの名無しさん2006/01/22(日) 01:17:17
>>239
なぜそう思う?

malloc も operator new も 返す型は void* なんですが。
0249デフォルトの名無しさん2006/01/22(日) 01:19:28
>245
ちょっと名前を汚して良いのなら
#define NAMESPACE_hogehoge namespace hogehoge {
#define END_OF_NAMESPACE_hogehoge }
とか?
0250デフォルトの名無しさん2006/01/22(日) 02:00:03
クラスBのオブジェクトをA.cppとC.cpp内で使いたいのですが下記のエラーが出てリンクできません。
どうすればよいでしょうか?

A.OBJ : error LNK2005: "class B b" (?b@@3VB@@A) はすでに C.OBJ で定義されています

(A.h)
#include <stdio.h>
#include "B.h"

extern B b;

class A
{

};

(A.cpp)
#include "A.h"

B b;

int main()
{
return 0;
}
0251デフォルトの名無しさん2006/01/22(日) 02:00:57
(B.h)
class B
{

};

(B.cpp)
#include "B.h"

(C.h)
#include "B.h"

extern B b;

class C
{

};

(C.cpp)
#include "C.h"

B b;
0252デフォルトの名無しさん2006/01/22(日) 02:04:01
a.cpp もしくは c.cpp の B b; をどっちか消せよw
0253デフォルトの名無しさん2006/01/22(日) 02:04:14
>>250
Bのクラス宣言だけをB.hppに残して、定義をB.cppに移動する。
0254デフォルトの名無しさん2006/01/22(日) 02:06:25
汎用的に使いたいってことなら、
a.cpp と c.cpp から B b; を消して b.cpp に書いて、
a.h と c.h から extern B b; を消して b.h に書いとけ。
0255デフォルトの名無しさん2006/01/22(日) 02:12:42
何もかもが間違っている気がする。
02562502006/01/22(日) 03:17:32
>>252
(B.h)
class B {
public:
int hoge;
};
(C.h)
#include "B.h"
extern B b;
class C {
public:
void func();
};
(A.cpp)
#include "A.h"
//B b;
int main() {
b.hoge;
return 0;
}
(C.cpp)
#include "C.h"
B b;
void C::func() {
b.hoge;
}
これで使い方合ってるでしょうか?
02572502006/01/22(日) 03:19:03
>>253
(B.h)
class B {
};
(B.cpp)
#include "B.h"
B b;
こうですか?

>>254
error C2146: 構文エラー : ';' が、識別子 'b' の前に必要です。
fatal error C1004: 予期せぬ EOF が検出されました。
コンパイルエラーになりました。
0258デフォルトの名無しさん2006/01/22(日) 03:23:31
#include "stdafx.h"

あと氏ね。
0259デフォルトの名無しさん2006/01/22(日) 03:34:37
パブロフの犬を思い出した
0260デフォルトの名無しさん2006/01/22(日) 03:50:39
>>258
言葉が悪いな。それで教えているつもりか。
まぁヒントにすらなっていないが、
うむごくろう。
0261デフォルトの名無しさん2006/01/22(日) 05:13:09
短気は損気。
気長にマターリ…ねみぃ。。。
0262デフォルトの名無しさん2006/01/22(日) 05:24:47
次期バージョンのC++では、
list<list<int>> l;
と>>の間にスペース入れなくてよくなりそうな感じだね。
0263デフォルトの名無しさん2006/01/22(日) 07:58:00
禿もそうしたいってD&Eに書いてたね
0264デフォルトの名無しさん2006/01/22(日) 08:06:40
>>262 逆になんで今はスペース入れなきゃならないのか、理由がわからない。
0265デフォルトの名無しさん2006/01/22(日) 08:15:54
構文解析上の都合
0266デフォルトの名無しさん2006/01/22(日) 08:23:47
空白が入ってないと、パーサが混乱するんだろうか。
0267デフォルトの名無しさん2006/01/22(日) 08:24:57
レキサは基本的に最長一致だから、構文解析の情報を持たせないと
>>を1つのトークンと見なしちゃう
0268デフォルトの名無しさん2006/01/22(日) 08:33:59
じゃ、古典的な lex & yacc なんかじゃ
パースできないってことか。
現代のコンパイラはレキシカルアナライザが分離してないのが当たり前?
0269デフォルトの名無しさん2006/01/22(日) 09:15:03
質問です
1万桁とかの計算はどうするんですか?
型宣言でlong doubleまでは掛け算割り算できるけどそれ以上の仕方が分かりません
そこら辺も自作しないといけないんですk?
0270デフォルトの名無しさん2006/01/22(日) 09:18:49
多倍長演算
自作するなりそこらに落ちてるライブラリを使うなりご自由に
0271デフォルトの名無しさん2006/01/22(日) 09:21:42
>>270 有名どころっていえばなんでしょうか?
GNU多倍長整数ライブラリですか?
0272デフォルトの名無しさん2006/01/22(日) 09:23:47
って、>>269 は実数演算がしたいみたいだから、
GNU MP ライブラリでいいのか。
0273デフォルトの名無しさん2006/01/22(日) 09:23:58
個人的にはboost::bigintに期待してたり
0274デフォルトの名無しさん2006/01/22(日) 13:33:42
少なくとも g++ と cl.exe は予約語 export をさっさとサポートしる。
話はそれからだ。
0275デフォルトの名無しさん2006/01/22(日) 14:10:23
>>274
exportはサポートしなくても標準に合致している事が保証されたから、
それはなかなか難しいだろう。
0276デフォルトの名無しさん2006/01/22(日) 16:53:40
>>275
それソースプリーズ
0277デフォルトの名無しさん2006/01/22(日) 18:36:00
メンバー関数(func1, func2関数)のポインタをvectorに登録して(Init関数)、
callFunc関数で登録した関数をコールしたいのですが、以下のエラーで
コンパイルできません。コールの方法が間違っていますでしょうか?

Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
func.cpp:
エラー E2314 func.cpp 49: 関数でないものを呼び出している(関数 Func::callFunc(st ::string) )
*** 1 errors in Compile ***

-- ここから --
class Func {
public:
void Init();
int callFunc(std::string);
private:
typedef int (Func::*PFUNC)(std::string);
std::vector<PFUNC> funcs;
int index;
int func1(std::string);
int func2(std::string);
};
0278デフォルトの名無しさん2006/01/22(日) 18:36:37
続きです。

void Func::Init()
{
funcs.push_back(&Func::func1);
funcs.push_back(&Func::func2);
index=0;
}

int Func::func1(std::string str)
{
std::cout << "This is func1: " << str << "\n";
return 1;
}

int Func::func2(std::string str)
{
std::cout << "This is func2: " << str << "\n";
return 2;
}

int Func::callFunc(std::string str)
{
PFUNC pf = funcs[index++];
return (&pf)(str); // ここでエラー
}
0279デフォルトの名無しさん2006/01/22(日) 18:45:50
>>277
メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。

> typedef int (Func::*PFUNC)(std::string);
この typedef ができるのに呼び出し方がわからないってのは、不思議な感じだな。
0280デフォルトの名無しさん2006/01/22(日) 18:56:29
>>279
ありがとうございます。277ですが、C言語は知っているので、
typedefはなんとなくわかっているつもりですが・・・。

>メンバ関数のポインタから関数呼び出しをするには、演算子 ->* または .* を使う。

すみません、具体的にどのように変更すればよいということですしょうか?
return (&pf)(str);を変更するということですよね?

0281デフォルトの名無しさん2006/01/22(日) 19:02:35
>>280
ちっとは調べてから訊こうな。
http://www.google.co.jp/search?q=%E3%83%A1%E3%83%B3%E3%83%90%E9%96%A2%E6%95%B0+%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF+%E6%BC%94%E7%AE%97%E5%AD%90
0282デフォルトの名無しさん2006/01/22(日) 19:07:26
>>281
すみません、君らと違って暇じゃないもので・・・
0283デフォルトの名無しさん2006/01/22(日) 19:09:07
前方イテレータの方がランダムアクセスイテレータよりスピードやメモリ使用量が優れているとおっしゃるのですか?
0284デフォルトの名無しさん2006/01/22(日) 19:11:35
>>281
コンパイルできますた。
return (this->*pf)(str);
でした。
0285デフォルトの名無しさん2006/01/22(日) 19:27:40
>>283 誰もそんなこと言ってないんじゃないかな。
0286デフォルトの名無しさん2006/01/22(日) 22:40:10
>>282
暇じゃないなら2chに書き込んで都合のいい回答を待つより
自分で調べた方がいいと思う。絶望的に調べ物が下手とかでないなら。
0287デフォルトの名無しさん2006/01/22(日) 22:49:30
>>280
禿本くらい読めアフォ
0288デフォルトの名無しさん2006/01/22(日) 23:06:16
だから禿禿言うなって何回も言ってるだろ!
いい加減起こるぞほんとに
0289デフォルトの名無しさん2006/01/22(日) 23:49:37
何が起こるんだろうか…もしや禿(ry
0290デフォルトの名無しさん2006/01/23(月) 00:10:53
>>287
禿本なんてよまねーよ、カス
0291デフォルトの名無しさん2006/01/23(月) 00:14:03
>>290 そんなこと言うとあなた、禿が起こりますよ。
0292デフォルトの名無しさん2006/01/23(月) 04:21:23
禿の頭舐めたい
0293デフォルトの名無しさん2006/01/23(月) 09:20:54
甘酸っぱいよ
0294デフォルトの名無しさん2006/01/23(月) 09:28:13
プログラミング言語C++:第3版の「7.7関数ポインタ」とかは
四段ですが。別のところに載ってますか?
0295デフォルトの名無しさん2006/01/23(月) 09:56:35
規格書読めや禿げ
0296デフォルトの名無しさん2006/01/23(月) 10:45:51
>>294
15.5
0297デフォルトの名無しさん2006/01/23(月) 11:50:47
>>295
おっしゃる通りです。
読んで来ます。

>>296
禿しくThanXです。
0298Stroustrup2006/01/23(月) 12:00:09
(;`Д´)・・・・・
0299デフォルトの名無しさん2006/01/23(月) 14:27:42
規格、お題目、並べ立てるやつは口先だけの場合が多い
0300デフォルトの名無しさん2006/01/23(月) 17:14:37
>>299
お前も口先だけじゃないか。
0301デフォルトの名無しさん2006/01/23(月) 19:48:36

「禿本読め、コンパイラのマニュアル読め、コード読め。」
これらは相談スレ的には酷すぎんか?

「入門書読め」ならわかるが。

0302デフォルトの名無しさん2006/01/23(月) 19:57:40
>>301
そうだね、あんまり禿、禿、言うのはかわいそう。
0303デフォルトの名無しさん2006/01/23(月) 20:00:59
>>301
禿本は我慢して読むだけの価値があると教えているわけだが?
使い方1つで原価の1万倍くらい当たる本だぞ
0304デフォルトの名無しさん2006/01/23(月) 21:13:35
正直、禿本も読まないでコード書いてるようなヤシとは仕事したくない。
集中して読めば一週間で読了できるのに。理解が進むのはさらに後だとしても。
0305デフォルトの名無しさん2006/01/23(月) 21:25:56
禿本を集中して一週間で読ませるようなヤツもどうかと思うがなw
0306デフォルトの名無しさん2006/01/23(月) 21:26:13
読了しただけで意味あるような禿本なんてあったっけ?
0307デフォルトの名無しさん2006/01/23(月) 21:35:16
>>300
なんだと、おれはちゃんと金もらうだけのことをやってるぞ!
0308デフォルトの名無しさん2006/01/23(月) 21:37:13
>>307
でも、もらってないんだろ? 満額
0309デフォルトの名無しさん2006/01/23(月) 21:40:10
禿本高杉
0310デフォルトの名無しさん2006/01/23(月) 21:46:26
このスレがお笑いスレになっている件について。
0311デフォルトの名無しさん2006/01/23(月) 22:39:51
もったいぶってる奴が多いな
0312デフォルトの名無しさん2006/01/23(月) 23:06:07
C++の本で邦人の著者は柏原正三の一人勝ちなんじゃないかのお。
0313デフォルトの名無しさん2006/01/23(月) 23:16:19
>>312
(゚Д゚)ハァ?
0314デフォルトの名無しさん2006/01/23(月) 23:52:03
>>308
もらってますが何か?
0315デフォルトの名無しさん2006/01/24(火) 00:24:47
なにこのスレ
0316デフォルトの名無しさん2006/01/24(火) 09:26:41
僕の禿本は湿気を吸ってなんだかペラペラになってます
0317デフォルトの名無しさん2006/01/25(水) 08:57:53
2000にspecial editionなんてのが出てるけど、
あれは何か新しいことが書いてあるの?
0318デフォルトの名無しさん2006/01/25(水) 12:42:18
>>317
http://public.research.att.com/~bs/bs_faq.html#SE

ハードカバーになり、その分値段が上がったこと以外の違いはない。
ただし、3rd ed.の初刷からは、記述ミスの修正が1000以上なされている。
0319デフォルトの名無しさん2006/01/25(水) 12:58:51
>>318
残念ながら不正解。直後の、
「As a heavy C++ user, I find that significant. There are also the two new appendices (just over 100 pages; available for download: Locales and Standard-Library Exception Safety).」
を見落としている。まぁダウンロードできるものだが。
0320デフォルトの名無しさん2006/01/25(水) 13:23:24
>>316
俺の禿本は持ちすぎて表紙が溶けかかってる
0321デフォルトの名無しさん2006/01/25(水) 20:04:09
Cだとリスト構造を作るために、構造体に自分と同じ型のポインタの
prevやnextといったメンバを持たせたりするけど、C++の場合は
全てvectorやlistで管理するんですか?
0322デフォルトの名無しさん2006/01/25(水) 20:08:05
>>321
Cスタイルで書きたければCスタイルで書けばいい話じゃ?
0323デフォルトの名無しさん2006/01/25(水) 20:23:33
>>321 まぁそういう便利なクラスライブラリがあるから、
自分でわざわざ作る必要はないけど、
特殊なデータの保持の仕方をしたければ
自分で作ればいいんじゃない?
0324デフォルトの名無しさん2006/01/25(水) 20:28:45
けど基本的にSTLでできることはSTLでするってのが道理だろうな
STLの奴は全部、ある程度以上のパフォーマンスを出せることが
保証されてるわけだし
0325デフォルトの名無しさん2006/01/25(水) 20:29:30
自分で書くメリットがまったくない。
STLを使うと
・素晴らしいアルゴリズムの恩恵を受けられる
・STLは世界共通
・例外安全
・速い
・メモリ領域に関して無駄に悩む必要がなくなる

他にもいろいろあるだろう。
自分で直線的なリスト形式を実装するのは、
Chain Of Responsivilityのときくらい。
0326デフォルトの名無しさん2006/01/25(水) 20:38:44
速いかどうかは微妙だなぁ。
カリカリにチューンするならSTLは使わないけど。
0327デフォルトの名無しさん2006/01/25(水) 20:55:26
STL 多少の非効率はあるよね。
例えばリストなど、新規ノードの追加で必ずコピーコンストラクタが呼ばれる。
ポインタ型にすれば解決できるが、参照とサイズが無駄になる。

0328デフォルトの名無しさん2006/01/25(水) 20:57:52
>>327 もうその辺は気にせず、boost::shared_ptr を食わせたりしてる。
マジでかりかりにチューンが必要な場合は、
スクラッチからコンテナを書くな。

最近コンテナ書いたのって、歯抜けを許すリングバッファかなぁ。
0329デフォルトの名無しさん2006/01/25(水) 21:00:48
STLのスタイルがどうにも合わない
0330デフォルトの名無しさん2006/01/25(水) 21:03:34
>>329
マンコをチンポに合わせるんじゃない。
チンポをマンコに合わせるんだ。
0331デフォルトの名無しさん2006/01/25(水) 23:55:08
ネストしたクラスなんですが

class A
{
private:
 typedef int Hoge;
 static Hoge aaa;
public:
 class B
 {
 public:
  B() { Hoge i = A::aaa; }
 };
};

A::BがAのプライベートメンバにアクセスしても怒られないのですが
これは暗黙に friend class B; が宣言されると解釈していいのでしょうか?
■ このスレッドは過去ログ倉庫に格納されています