■過去ログ置き場に戻る■ 1- 前250 次250 最新50


[memo] "9999999999_00.html#R20" という感じで、URLの最後に "#RレスNo" を追加すると幸せになれます。

C++相談室 part44
501 名前:デフォルトの名無しさん :2005/10/29(土) 20:32:46
他意があっても無問題に五票

502 名前:デフォルトの名無しさん :2005/10/29(土) 20:39:10
areと書けば無問題

503 名前:デフォルトの名無しさん :2005/10/30(日) 01:10:20
>>480
namespace foo と class foo は同じスコープに存在できないよ。

504 名前:デフォルトの名無しさん :2005/10/30(日) 05:32:16
こんなコードを書いてもよいのでしょうか。

struct MyData
{
int x, y, z;
};

MyData mydata[2] = {{1, 2, 3}, {4, 5, 6}};

うまくいっちゃうのですが、MyDataにコンストラクタはいらないのかなあと。
よろしくお願いします。

505 名前:デフォルトの名無しさん :2005/10/30(日) 05:41:08
>>504
いいよ。
その例だと、コンストラクタを作ったら初期化が面倒になるだろう。

506 名前:デフォルトの名無しさん :2005/10/30(日) 07:29:32
上のほうにあるレスですが、
>>445>>446
むしろ、time_t now_ (time (0)); がわからないんですが。
NULLは0でよいんでしょうか?だったらNULLなんかいらないような。
それともCとC++で違ってるのでしょうか?

507 名前:デフォルトの名無しさん :2005/10/30(日) 09:28:29
>>506
time(NULL)でいいよ。教条主義者と勘違い野郎は0にするかもしれないけど。

508 名前:デフォルトの名無しさん :2005/10/30(日) 09:38:22
>>506
C++でNULLは0と同じ。
Cだと(void *)0になっていることがあるのだが、
C++ではvoid *から他のポインタ型への変換にはキャストがいるので単に0となっている。

で、いっそのこと0使えやということになって、
それを実践しているが507のいう教条主義者ということになる。(含む俺)

509 名前:デフォルトの名無しさん :2005/10/30(日) 10:31:36
俺も教条主義者だ。0を使え。>>506

510 名前:デフォルトの名無しさん :2005/10/30(日) 10:52:06
C++で敢えてNULL使う派もいるなんて初めて知った orz

511 名前:デフォルトの名無しさん :2005/10/30(日) 11:02:17
NULLを使う波。
NULLならヌルポインタを関数に渡していると一目でわかる。
0を渡すと数値渡してるのかポインタ渡してるのか判らん。

512 名前:デフォルトの名無しさん :2005/10/30(日) 11:15:23
おれも>>511に賛成NULLぽ

513 名前:デフォルトの名無しさん :2005/10/30(日) 11:27:30
昔はNULLだったがその後禿に合わせて0にするようにしたなあ

514 名前:デフォルトの名無しさん :2005/10/30(日) 11:32:56
>>511のように引数に使うと見分けをつけやすいけど、
結局エラー時にコンパイラには補足されない点では同じだし
int *p = NULL;
よりは
int *p = 0;
の方が自然かな、というところで最近は0派。
どっちを使ってても実務で問題になったことはないし、好みの問題だろ。

515 名前:デフォルトの名無しさん :2005/10/30(日) 11:49:25
NULLと0の議論は別スレ立ててやれやう゛ォケ共

516 名前:デフォルトの名無しさん :2005/10/30(日) 11:51:27
>>515
いや、別スレ立ててるほどのものでもないでしょ。
過去スレみれば腐るほど議論がされているような気がするのだが?

517 名前:デフォルトの名無しさん :2005/10/30(日) 11:54:58
分かったから出てけ

518 名前:デフォルトの名無しさん :2005/10/30(日) 11:55:04
つまりどっちでもいいでFA。

519 名前:デフォルトの名無しさん :2005/10/30(日) 11:55:34
好きな方使えばいーじゃん
俺は>>514みたらNULLの方が分かりやすいなとも思うし人それぞれ

520 名前:デフォルトの名無しさん :2005/10/30(日) 12:06:36
ところでC++/CLIにはnullptrキーワードが導入され、
通常のポインタに対しても使えるようになる。

521 名前:デフォルトの名無しさん :2005/10/30(日) 12:11:21
void f(int n);
f(NULL);
ていう恐らく意図とは違うコードが
f(nullptr);
でエラーとして捕らえられるってことか。
便利やも。

でもC++/CLIじゃなぁ(´A`)

522 名前:デフォルトの名無しさん :2005/10/30(日) 14:48:44
>>521
C++って、いつからコマンドラインインタフェースになったの?

523 名前:デフォルトの名無しさん :2005/10/30(日) 14:51:21
Common Language Infrastructureだっけ?

524 名前:デフォルトの名無しさん :2005/10/30(日) 18:07:47
#include <iostream>
using namespace std;

int foo(struct null_ptr*) {cout << " null po " << endl;}
int foo(int i){cout << " int " << endl; }

int main()
{
foo(0);
foo(static_cast<null_ptr*>(0));
}

ってなかんじのコードなら見たことがある。


525 名前:デフォルトの名無しさん :2005/10/30(日) 18:09:51
>>524
ガッ・・・・してもいい?w

526 名前:デフォルトの名無しさん :2005/10/30(日) 18:20:17
最前画面のウィンドウにマウス左クリックしたメッセージを流したいのですが

hWnd = GetForegroundWindow();
SendMessage(hWnd,WM_LBUTTONDOWN,0,1);
SendMessage(hWnd,WM_LBUTTONUP,0,1);

では動きません、どうすればよいですか?

527 名前:デフォルトの名無しさん :2005/10/30(日) 18:25:11
>>526
先ずはスレ違いということを認識することから始めよう。

528 名前:デフォルトの名無しさん :2005/10/30(日) 20:55:12
>>527
すまん、スレ違いだったようだ

529 名前:デフォルトの名無しさん :2005/10/31(月) 07:39:44
NULL を使うこと自体は構わないが、
<cstddef> とかのインクルードをせずに
予約語のごとく使う奴は許さない。

530 名前:デフォルトの名無しさん :2005/10/31(月) 17:08:30
何かしらのライブラリをインクルードすれば#define NULL 0がついてくるんだけどな。

531 名前:デフォルトの名無しさん :2005/10/31(月) 22:10:23
インクルードで思い出したが、size_tやらptrdiff_tにstd::をつけるべきか否かでいつも迷う。

532 名前:デフォルトの名無しさん :2005/10/31(月) 22:10:56
<cstddef>のほかにC由来のヘッダでは<cstdio> <cstdlib> <cstring> <ctime>でNULLが定義されることになっている。

533 名前:デフォルトの名無しさん :2005/10/31(月) 22:13:17
>>531
<c〜>のヘッダを使っていればもちろん必要。

<〜.h>のヘッダでは内部でusingされているということになっているから、
規格通りの処理系ではstd::size_tなどとしても使えるはず。

534 名前:デフォルトの名無しさん :2005/10/31(月) 23:40:56
http://www.open-std.org/jtc1/sc22/wg21/docs/lwg-active.html#456

535 名前:デフォルトの名無しさん :2005/10/31(月) 23:46:06
C++で実装するときでC標準ライブラリを使うとき、
<*.h>を使う奴はいないよな?

536 名前:デフォルトの名無しさん :2005/10/31(月) 23:49:13
>>535
いるわよ〜(*^o^*)

537 名前:デフォルトの名無しさん :2005/11/01(火) 11:48:33
勘弁してくれ。

538 名前:デフォルトの名無しさん :2005/11/01(火) 12:43:55
メンバ関数のポインタ配列を順次実行しようとしています

class CTest
{
private:
 void func1() {};
 void func2() {};
public:
 static void (CTest::*fpTable[])(void);
};

void (CTest::*CTest::fpTable[])(void) = {
 &CTest::func1,
 &CTest::func2,
 NULL,
};

void func()
{
 CTest test;

 void (CTest::**pFList)() = test.fpTable;
 for (; *pFList; pFList++) {
  (CTest::*pFList)();
 }
}

関数コールするところで、error C2059: 構文エラー : '<tag>::*' が出てしまうんですが(VC6)
なにか対策無いでしょうか?(俺に聞けスレからの誘導です)



539 名前:デフォルトの名無しさん :2005/11/01(火) 13:19:26
>>538
(CTest::*pFList)();

(test.**pFList)();

というか、あまりメンバ関数へのポインタについて理解してないようだから
無理にそういう書き方をしないで、boost::functionとboost::bindを組み合わせて使っておくのが無難かと

540 名前:デフォルトの名無しさん :2005/11/01(火) 13:30:05
理解してないなら理解すればいいだろ

541 名前:デフォルトの名無しさん :2005/11/01(火) 14:24:18
>>539
サンクスです
今の仕事場、boostはおろか、STLも禁止なんです
正直、関数ポインタはあまり使わないんで、勉強し直すつもりです

542 名前:デフォルトの名無しさん :2005/11/01(火) 14:27:20
>>541
禁止キター
その仕事場、逃げたほうが良いんじゃないか。

543 名前:デフォルトの名無しさん :2005/11/01(火) 15:07:24
Boostはともかく(うちでは使ってるけど)としてSTL禁止とかワロス

544 名前:デフォルトの名無しさん :2005/11/01(火) 15:14:29
古い処理系で既に作られているプログラムのエンハンスなんかでは
よくある話なんでないの?

545 名前:デフォルトの名無しさん :2005/11/01(火) 17:02:43
エラトステネスのふるいを書こうとしてます.Python で言うところの

def sieve(xs):
  if (len(xs) == 0): return []
  else: return [xs[0]] + sieve([y for y in xs[1:] if y % xs[0] != 0])
print sieve(range(2,1000))

というコードは,C++ ではどれくらい簡単に書けますか?

# Pythonではリストの加算はリストの隣接を表します.
# xs[1:] はリストの二番目の要素から後の部分リストです.

546 名前:デフォルトの名無しさん :2005/11/01(火) 17:46:59
>>545
#include <list>
#include <iostream>
#include <functional>
#include <iterator>
#include "boost/lambda/lambda.hpp"
#include "boost/lambda/bind.hpp"
namespace lambda = boost::lambda;
template<typename Out>
void seive(std::list<int> xs, Out out)
{
  while(!xs.empty())
  {
    int p = xs.front();
    *out++ = p;
    xs.pop_front();
    xs.erase(std::remove_if(xs.begin(), xs.end(), 
          lambda::bind(std::equal_to<int>(), 0, lambda::bind(std::modulus<int>(), lambda::_1, p))),
        xs.end());
  }
}
int main()
{
  std::list<int> x;
  for(int i = 2; i <= 1000; i++)
    x.push_back(i);
  typedef std::ostream_iterator<int> oii;
  seive(x, oii(std::cout, " "));
}

547 名前:545 :2005/11/01(火) 18:24:57
>>546
remove_if が algorithm のほうの remove_if なので,せっかく list を使っていても,そのメリットがありません.
(algorithm の remove_if は普通は内部で remove_copy_if を呼ぶので,コピーが発生してしまいます)

あと,一応結果を保持しておきたいです(で,できればそっちでもコピーは発生させたくない).

コピーをたくさん発生させてもいいなら,イテレータを回して↓な感じなんですが.
  vector<int> primes(2000);
  int k = 2; generate(primes.begin(), primes.end(), var(k)++);
  vector<int>::iterator it, last;
  for (it = primes.begin(), last = primes.end(); 
       it != (last = remove_if(it+1, last, _1 % *it == 0)); ++it);
  primes.erase(last, primes.end());

548 名前:546 :2005/11/01(火) 18:42:13
>remove_if が algorithm のほうの remove_if なので,せっかく list を使っていても,そのメリットがありません.
その通り。

>あと,一応結果を保持しておきたいです(で,できればそっちでもコピーは発生させたくない).
それだと標準アルゴリズムでは扱いきれないはず。
手でループを回すのが一番かと。

549 名前:デフォルトの名無しさん :2005/11/01(火) 20:08:20
>>535
なんで駄目なんだ
<windows.h>
<stdio.h>
って風に.hで揃えたいじゃないか。
<vector.h><map.h>

550 名前:デフォルトの名無しさん :2005/11/01(火) 20:18:17
>>549
つ[namespace]

551 名前:デフォルトの名無しさん :2005/11/01(火) 21:22:44
>>549
いつの時代の人間ですか?

552 名前:デフォルトの名無しさん :2005/11/01(火) 22:18:54
そもそもヘッダに.hが無いのって名前空間を考慮してないコードと.hがついた
ヘッダと互換性を残すためなんだっけ?それだったらstdioくらいは良さそうなもんだが。

553 名前:デフォルトの名無しさん :2005/11/01(火) 23:13:27
Borland Turbo C++ 1.01だとiostream.hにしないと怒られたお(;^ω^)

554 名前:デフォルトの名無しさん :2005/11/01(火) 23:34:03
>>539
っていうか、
玄人は**pFListなんてやらないで、*pFList[]にするよ。
今更ポインタできまつ!おらできまつ!流行んない。


555 名前:デフォルトの名無しさん :2005/11/01(火) 23:39:13
class CBase{
public:
    int x_, y_;

    CBase(int x = 0, int y = 0){
        x_ = x; y_ = y; 
    }
};
// 上のクラスはめっちゃ適当です。
// ソート用に演算子のオーバーロード
bool operator < (CBase &a, CBase &b){
    return a.x_ < b.x_;
}

std::list<CBase *> ObjectList;
CBase* BB = new CBase(100, 20);
CBase* BBA = new CBase(200, 20);
CBase* BBB = new CBase(150, 20);

ObjectList.push_back(BB);
ObjectList.push_back(BBA);
ObjectList.push_back(BBB);

// ここでソートしたいがうまくいかない
ObjectList.sort();

CBaseクラスのx_の値でソートしたいのですがうまくいかないんですができないんでしょうか?
std::list<CBase *> ObjectListをstd::list<CBase> ObjectListにして実体渡せばソートできるみたいなんですが
どなたか回答お願いします。


556 名前:デフォルトの名無しさん :2005/11/01(火) 23:42:55
>>555
ソートしたければSTLのソートアルゴリズムを使え。

557 名前:デフォルトの名無しさん :2005/11/01(火) 23:46:58
>>555
リストのソートは比較の関数オブジェクトを渡すことができる

558 名前:デフォルトの名無しさん :2005/11/01(火) 23:58:26
'ex' 内の 'test' へのアクセスがあいまいです。
とエラーがでるのですが、何がいけないのでしょうか?

template <typename T> struct base
{static void test(T){}};

struct ex :public base< int >,public base< int* >
{};

int main()
{
int a;
ex::test(a);
ex::test(&a);
}

559 名前:デフォルトの名無しさん :2005/11/02(水) 00:00:59
test(int) と test(int*) が衝突している。


……ってあれ? コレで良いんだっけ?

560 名前:558 :2005/11/02(水) 00:27:50
>>559
どうも。

using base<int>::test;
using base<int*>::test;

usingしたらVC7.1で通りました。(VC6だとだめぽ)

561 名前:デフォルトの名無しさん :2005/11/02(水) 00:43:14
>>558
そのエラーメッセージおかしいね。
gccでは
error: `test' is not a member of `ex'
error: `test' is not a member of `ex'

と出る。規格ではどうなってるんだっけか。

562 名前:デフォルトの名無しさん :2005/11/02(水) 01:06:03
>>555
-ObjectList.sort();
+struct Local {static bool Dereference_Less (const CBase *lhs, const CBase *rhs) {return lhs->x_ < rhs->x_;}};
+ObjectList.sort(&Local::Dereference_Less);

bool operator < (CBase &a, CBase &b)

bool operator < (const CBase &a, const CBase &b)



563 名前:デフォルトの名無しさん :2005/11/02(水) 03:46:37
> 10.2/2
> (前略)
> If the resulting set of declarations are not all from sub-objects of the same type,
> or the set has a nonstatic member and includes members from distinct sub-objects,
> there is an ambiguity and the program is ill-formed.
隠蔽を考えた上での member name lookup の結果が、
1) 同じ型の sub-objects 由来のものではない場合
2) 非静的メンバを持ち、かつ別個の sub-objects 由来のものを含む場合
のいずれかである場合、曖昧であり ill-formed である、そうな。
オーバーロードの解決はこの後(結果が曖昧でなかった場合)だそうで。
D&E (日本語訳) p.534 にも(非静的メンバだけど)例があった。

564 名前:デフォルトの名無しさん :2005/11/02(水) 09:43:01
>>563
解説サンクス。
>>561で生じたエラーは、base<int>::test と base<int*>::test はあるが、
ex::test はないために生じたのだと思う。VC7.1は、これらをまるでex::test
のように扱うために、外部からアクセスした時に曖昧エラーが出ているが、
本来は gcc のように、not found エラーとして処理すべきかと。


565 名前:デフォルトの名無しさん :2005/11/03(木) 02:45:22
m_cell &= m_cell ^ rhs.m_cell;



m_cell = m_cell & (m_cell ^ rhs.m_cell);

は同じではないのですか?


566 名前:デフォルトの名無しさん :2005/11/03(木) 02:50:38
>>565
どういうこっちゃ。演算子のオーバーロードとかは無しという方向で?

567 名前:デフォルトの名無しさん :2005/11/03(木) 03:56:11
class base{
}

class parent:public base{

}

class player{
void inc(base*){
for(int i=0;i<10;i++){
(base+i)->XXX();
}
}
main(){
parent a[10];
player p;
p.inc(a);

}

のように,基底クラスのポインタを扱う関数incに派生クラスの配列のポインタを与えると
エラーが出てしまいます.(実行可能ですが値が破綻します)
そもそもクラスの配列自体がナンセンスなのでしょうか?



568 名前:デフォルトの名無しさん :2005/11/03(木) 04:08:33
>>565
後者は一時オブジェクトがよぶんに生成される可能性がある。
m_cellが何かによって、同じ効果のある文かどうかは変わる。


569 名前:デフォルトの名無しさん :2005/11/03(木) 04:16:31
>>567
baseと、baseから派生されたparent(ふつうはderivedと名付けた方がわかりやすいと思う)のサイズが
まったく同じでない場合、結果は不定になる。baseのサイズを元にしてポインタ演算が行われるからである。

たいていの場合は派生クラスの方にメンバが追加されているなどで大きさが異なるので
(何をしているかが分からない限り)配列をポリモーフィズム的に扱うことは避けた方がよい。


570 名前:デフォルトの名無しさん :2005/11/03(木) 04:27:59
エディタ等が入ってないPCで
Visual C++で作られた dllファイルを一行追加したいんだけど、
サクラを入れてみたけど、文字化けで指定のところが編集できませんでした。
なにで編集すれば文字化け解消できますか?

571 名前:デフォルトの名無しさん :2005/11/03(木) 04:37:06
>>570
釣りは他のスレで頼む。

Visual C++の問題なら → http://pc8.2ch.net/test/read.cgi/tech/1118781438/l50


572 名前:デフォルトの名無しさん :2005/11/03(木) 04:46:05
>>571
570です。釣りではなく、まじでした。
ご存知でしたら誘導先に建てましたのでお答えいただけません?

573 名前:567 :2005/11/03(木) 04:48:58
>>569
助言を参考にしますと,上記の例ではplayerクラス関数に
inc(derived*){}
を作り直すか,テンプレートを使用する必要があるということですね.
ありがとうございました.非常に良くわかりました.

574 名前:デフォルトの名無しさん :2005/11/03(木) 08:40:14
parent* a[10];
って風すれば要望みたすんじゃないの?


575 名前:565 :2005/11/03(木) 10:40:37
565です。

m_cell, rhs.m_cell 共に bool です。

だから、&=, ^, =, & は全てデフォルトの演算子ですよね?


576 名前:デフォルトの名無しさん :2005/11/03(木) 14:24:05
>>575
その2つの式が同じバイナリを吐くか、もしくは違うバイナリを吐くかは、
コンパイラにより、さらに最適化レベルにもよる。

一般的に言って、上の式の方がより最適化されたバイナリを吐く可能性
が大きいが、規格では何も決められていない。

577 名前:567 :2005/11/03(木) 15:02:15
>>574
指南いただいた内容より,ポインタの配列を使用しても,実体はparentクラスのサイズ分が確保されるので,
baseクラスのポインタのインクリメントは不可能(不定)なのではないでしょうか?
気が向いたらご返信願えればと.

578 名前:デフォルトの名無しさん :2005/11/03(木) 19:11:55
>>577
sizeof(base) != sizeof(parent)であってもsizeof(base*) == sizeof(parent*)
厳密には実装依存か?


579 名前:デフォルトの名無しさん :2005/11/03(木) 19:16:47
>baseクラスのポインタのインクリメントは不可能(不定)なのではないでしょうか?
>>574の例では、実際にインクリメントするのはbaseへのポインタのポインタだから、
問題ない。

580 名前:567 :2005/11/03(木) 20:12:33
>>578 >>579
なるほど,そのようにインクリメントすればOKなのですね.
これで派生クラスごとに場合分けをしなくてすみそうです.
皆様の適切なアドバイスありがとうございました.

581 名前:デフォルトの名無しさん :2005/11/03(木) 22:31:46
テンプレートクラスで
template<class T> class CHandleAaa
というのがあったときにTがあるクラスCAaaを継承したクラス限定
という制限をかけるにはどうすればいいですか?
TがCAaaの派生クラスで無い場合コンパイルで怒られたいです。


582 名前:デフォルトの名無しさん :2005/11/03(木) 22:39:46
>>581
boostのtype_traitsのis_base_ofとBOOST_STATIC_ASSERTを組み合わせればいい。

583 名前:デフォルトの名無しさん :2005/11/03(木) 22:41:56
そういやtype_traitsは標準入り決定だけど、STATIC_ASSERTとかはどうなってるの?

584 名前:デフォルトの名無しさん :2005/11/03(木) 22:51:37
>>582
ありがとうございます。

585 名前:デフォルトの名無しさん :2005/11/04(金) 18:51:15
メンバ関数へのポインタの配列をメンバ変数として持たせたいのですが、

class TestClass
{
public:
typedef void (*LPFUNC_VOID_VOID)();
LPFUNC_VOID_VOID m_lpFunc[3];
…(略)…
void Draw00(void);
void Draw01(void);
void Draw02(void);
…(略)…
};

とし、コンストラクタの中で

m_lpFunc[0]=&TestClass::Draw00;

と代入するとcannot convert〜というエラーが出ます。TestClass::LPFUNC_VOID_VOIDとしてもエラーが出ます。
また、メンバ関数から呼び出そうと

(this->*m_lpFunc[1])();

とするとこれもエラーになるようです。
VC++6.0の時はこんな感じの記述でいけたのですが、VC++2003ToolkitとVC++2005Expressではだめでした。
このように、メンバ関数のポインタをメンバ変数として持ちたい場合、どのようにすればよろしいでしょうか?

586 名前:デフォルトの名無しさん :2005/11/04(金) 19:21:54
>>585
メンバーへのポインターに成ってないからじゃない。
>typedef void (*LPFUNC_VOID_VOID)();
>LPFUNC_VOID_VOID m_lpFunc[3];
void (TestClass::*m_lpFunc[3])();

587 名前:デフォルトの名無しさん :2005/11/05(土) 00:40:29
>564
> >>561で生じたエラーは、base<int>::test と base<int*>::test はあるが、
> ex::test はないために生じたのだと思う。VC7.1は、これらをまるでex::test
> のように扱うために、外部からアクセスした時に曖昧エラーが出ているが、
> 本来は gcc のように、not found エラーとして処理すべきかと。
言わんとするところをちゃんとつかめてないが、その解釈と↓の挙動は矛盾しない?
メッセージの違いは name lookup 段階での曖昧性に対する表現が違ってるだけなんじゃないかな?

#include <iostream>

struct A { static void func(void) { std::cout << 'A' << std::endl; } };
struct B : public A {};
struct C : public A {};
struct D : public B, public C {};
struct E : public A { static void func(void) { std::cout << 'E' << std::endl; } };
struct F { static void func(void) { std::cout << 'F' << std::endl; } };
struct G : public A, public F {};
struct H : public A, public F { static void func(void) { std::cout << 'H' << std::endl; } };

int main(void)
{
B::func(); // A
D::func(); // A
E::func(); // E
// G::func(); // error: `func' is not a member of `G'
H::func(); // H
return 0;
}

588 名前:585 :2005/11/05(土) 00:44:05
>>586
回答ありがとうございます。おかげでちゃんとエラーが出ずに動作するようになりました。
「関数のポインタ」じゃなくて「voidのポインタを返す〜」になってたんですね。

589 名前:デフォルトの名無しさん :2005/11/05(土) 00:45:55
質問です

ちょっと気になったことなんですが
ポインターの参照を返してみたいとふと思いついて
↓のようなものを書いてみたんですが、戻り値のところが
int*& のような見慣れない形になってるにもかかわらずコンパイルできました。
これって、大丈夫なんでしょうか?


int* a;//どこかで定義

int*& 関数()
{
return a;
}

590 名前:デフォルトの名無しさん :2005/11/05(土) 00:54:03
>>589
大丈夫。
ついでに、そういうことは習慣じゃなくて論理を基に考えるべきだと思う。

591 名前:デフォルトの名無しさん :2005/11/05(土) 00:58:13
でも毎回論理で考えると時間がかかるからそれも習慣にいれとけ

592 名前:デフォルトの名無しさん :2005/11/05(土) 01:03:19
#include <cstdio>
using namespace std;
int main (void)
{
int i=15,*p;
p = &i;
printf("%x %x %x %x %x\n",p,*p,&p,*&p,&*p);
}

実行結果
22ff74 f 22ff70 22ff74 22ff74

当然だね

593 名前:デフォルトの名無しさん :2005/11/05(土) 01:05:43
>>590>>591
早い回答ありがとう

なるほど、大丈夫ですか。
安心しました。

論理か・・ プログラムって意外と奥が深いんだなあ




594 名前:デフォルトの名無しさん :2005/11/05(土) 05:41:29
displayInt(int value){
 printf("INT: ");
 printf(" %d", value);
 printf(" (%08X)", value);
}

displayDouble(double value){
 printf("DOUBLE: ");
 printf(" %f", value);
 printf(" (%16X)", value);
}

displayString(char *value){
 printf("STRING: ");
 printf(" %s", value);
 printf(" (%08X)", value);
}

こういった感じの関数を、各組み込み型すべてについて作りたいのですが、テンプレート、あるいはオーバーロードなどをどういう風に書いたら、コードを短くできるでしょうか?
displayInt/Double/UCharなどと、String/WStringは別物と考えた方がいいのかもしれませんが・・・

595 名前:デフォルトの名無しさん :2005/11/05(土) 06:46:37
>>594
引数の型を表す名前は関数名に含めずに、オーバーロードを定義すればいい。
iostream を使うと、フォーマット文字を型ごとに変えてやる必要は無くなる。

INT, DOUBLE, STRING なんてのは、それぞれ書かないと無理だろうな。
各関数の3行目は意味が不明瞭なので手がつけられない。

596 名前:デフォルトの名無しさん :2005/11/05(土) 08:59:46
一行目はこんな関数を作り、displayでは最初にstd::cout << TypeName(x) << ": ";とすればいいだろ。
template<typename T>
inline const char *TypeName(const T& x)
{
    return typeid(x).name();
}
char *をchar *と表示させたくなければ特殊化すればいい。

3行目は各値のビット表現を出力したいということだろ。
こんなものを考えたが駄目だった。
std::cout  << std::hex << '(' << reinterpret_cast<const boost::uint_t<sizeof x * CHAR_BIT>::least&>(x) << ')';

597 名前:デフォルトの名無しさん :2005/11/05(土) 09:47:05
>>595
>INT, DOUBLE, STRING なんてのは、それぞれ書かないと無理だろうな。
typeid(int).name()でいけないか?

598 名前:デフォルトの名無しさん :2005/11/05(土) 10:48:22
>>596-597
nameが何を返すかは処理系依存だし、実際gccは「i4」だとか一見意味の分からない文字列を返すから使えない

599 名前:デフォルトの名無しさん :2005/11/05(土) 14:06:42
#include <cstdio> // use <boost/format.hpp> if boost is available
#include <iostream>
#include <iomanip>
#include <sstream>
#include <typeinfo>

template <typename T> struct type {
 inline static const char* name() throw() { return typeid(T).name(); }
 inline static const char* format() throw() {
  std::stringstream ss; ss << "%0" << sizeof(T)*2 << "X"; return ss.str().c_str();
 }
};
template <> struct type<int> {
 inline static const char* name() throw() { return "INT"; }
 inline static const char* format() throw() { return "%08X"; }
};
template <> struct type<double> {
 inline static const char* name() throw() { return "DOUBLE"; }
 inline static const char* format() throw() { return "%16X"; }
};
template <> struct type<char*> {
 inline static const char* name() throw() { return "CHAR*"; }
 inline static const char* format() throw() { return "%08X"; }
};

template <typename T> inline void display_type(const T& value) {
 using namespace std;
 cout << type<T>::name() << ": " << value << " (";
 printf(type<T>::format(), value); // OMG
 cout << ")";
}


600 名前:599 :2005/11/05(土) 14:21:41
int main() {
 int i = 12345678; double d = 1234.56; char* c = "test"; unsigned int j = 12;
 display_type(i); display_type(d); display_type(c); display_type(j);
 return 0;
}

問題を難しくしただけの希ガス(´д`)

「型」と「型の名前」、「型」と「型の出力フォーマット」を
プログラマが思うとおりにしなければならないなら、そのいちいちについて列挙するしかない。
template〜とか書くのがめんどくさい場合、マクロを使う:

#define TYPE(T, NAME, FORMAT) \
 template <> struct type<T> { \
  inline static const char* name() throw() { return NAME; } \
  inline static const char* format() throw() { return FORMAT; } \
 };

TYPE(int, "INT", "%08X")
TYPE(double, "DOUBLE", "%16X")
……

糞コードだな(鬱

601 名前:デフォルトの名無しさん :2005/11/05(土) 21:45:14
俺はconst std::type_info&をキーにしてstd::mapに格納できないかと考えた。
それは無理だろうけど、適当にラッピングすればキーに出来るのではないかと思う。

602 名前:  :2005/11/06(日) 01:37:03
ファイルからたくさんデータを読んでクラスのメンバ変数に保存してるんだけど。
(デフォルト値はある。ファイルで入力が無かった変数にはそれを使う)
で、質問なんだけど、その変数をpublic変数にしていつでも読めるようにしたい、
でも左辺値にはしたくないって時にどうやってる?

603 名前:デフォルトの名無しさん :2005/11/06(日) 01:42:29
>>602
「左辺値にする」の意味がよくわからないが、
それが「代入の対象となる」という意味なら、
public な const 参照メンバを置けばよさそう。

604 名前:デフォルトの名無しさん :2005/11/06(日) 01:50:33
>>603
レス、サンクス。

const参照メンバ?

public:
const int var1;
const double var2;
const string var3;

みたいな?

デフォルト値があって、入力があった時だけはメソッドで読み込んで値を変えたい。
外部で使用するときは参照するだけ。値の変更は許さない、みたいな使い方。

でも、上だと値そのものが変更できないんじゃないのかな?


605 名前:デフォルトの名無しさん :2005/11/06(日) 01:53:22
本来は、単にprivate変数にすれば良さそうだけど、
参照したい変数がすっごく多くて、そのつど、その変数の値を返す
だけのメンバ関数を書きたくないんですよ。
だから、public変数にしたい。でも、値は好き勝手に変更できるようにしたくはない、って訳です。

606 名前:デフォルトの名無しさん :2005/11/06(日) 02:13:37
>>605
まとまったデータとして、struct などにまとめてはどうだ?

607 名前:デフォルトの名無しさん :2005/11/06(日) 02:31:23
>>604
class C
{
private:
 int v;
public:
 int const& rv;
 C() : rv(v) {}
};

すっごく多いってことなら、これも不味いんだろうな。
606 の言うように構造体にまとめて、
この方法と組み合わせるといいかもしれない。

それでも、奇妙なことせずに値参照用のメンバ関数を
用意するのが最善なのに変わりは無い。

608 名前:デフォルトの名無しさん :2005/11/06(日) 02:51:56
>>607
> 値参照用のメンバ関数を用意するのが最善なのに変わりは無い。

ああ、それ、いい方法があったら知りたい。
一つ一つの変数ごとに関数を用意するんじゃなくて、なんか汎用に使える方法ないのかな。


609 名前:デフォルトの名無しさん :2005/11/06(日) 03:05:06
#define READONLY(t, n) private: t n##_; public :const t& n() const {return n##_;}


610 名前:デフォルトの名無しさん :2005/11/06(日) 03:10:09
>>608
設計を見直すのはどうだろう。

折角クラスを設計しているのに内部データを曝け出すのは設計が悪い。
曝け出したいものが一括りにできるのならそうするべき(≒>606)だし、
条件付で曝け出す(≒>607)もいいが、本当に曝け出すべきかどうかも検討してみるべき。

611 名前:デフォルトの名無しさん :2005/11/06(日) 03:11:52
パフォーマンスを犠牲にしてもよければ、プロパティクラスを使う手はあるけど
そもそも変数の数が膨大という時点で設計を見直した方がいいかもしれない。

private:
 T ID_;
public:
 const T& ID() const { return ID_; }

を書けばいいということなら、これをマクロにして:

#define readonly(T, ID) \
 private: \
  T ID##_; \
 public: \
  const T##& ID##() const { return ID##_; }

というのはどうだろう?

class b {
 readonly(int, value)
};

試してないので間違いあるかも。

612 名前:デフォルトの名無しさん :2005/11/06(日) 03:12:34
考えることはみんな同じだなw

613 名前:デフォルトの名無しさん :2005/11/06(日) 03:15:10
クラスが一枚岩になってそう
一つの機能に絞ってまずは分割汁

614 名前:デフォルトの名無しさん :2005/11/06(日) 16:16:09
privateメンバに対するgetメソッドを自動的に作るようなスクリプトでも書けばすむ話じゃないのか?

615 名前:デフォルトの名無しさん :2005/11/06(日) 16:23:44
>>614
そんなことしたくなる場面では設計を見直すほうがいい。

616 名前:デフォルトの名無しさん :2005/11/06(日) 16:43:44
参照型は使い回しって出来ますか?

617 名前:デフォルトの名無しさん :2005/11/06(日) 16:52:40
使いまわしの意味がわからんが
初期化したら最後、変更はできない

618 名前:デフォルトの名無しさん :2005/11/06(日) 18:29:52

> 初期化したら最後、変更はできない

constの話じゃなくって?
だったら詳しく

619 名前:デフォルトの名無しさん :2005/11/06(日) 18:34:18
>>618
T& r を一度初期化したら &r は変更できない、ってこと。
それとは別に、 r = x という式は T が const 付じゃない限り有効。

620 名前:デフォルトの名無しさん :2005/11/06(日) 20:05:54
> T& r を一度初期化したら &r は変更できない、ってこと。

ごめん。意味がわからない。

int i,j;
....
int& k = i;
...
k=j;

これができないって意味じゃないね?


621 名前:デフォルトの名無しさん :2005/11/06(日) 20:07:23
× これができないって意味じゃないね?
○ これができないって意味じゃないよね?


622 名前:デフォルトの名無しさん :2005/11/06(日) 20:07:45
やってみたらいいのに

623 名前:デフォルトの名無しさん :2005/11/06(日) 20:09:40
Moreか無印のEffective C++呼んだ方が早いな

624 名前:デフォルトの名無しさん :2005/11/06(日) 20:10:53
>>620
ポインタとの対比で、

int i, j;

int *p = &i;
int &k = i;

p = &j; /* pの参照先を変えることはできるが */
&r = &j; /* もちろんこんなことはできないし、 */
r = j; /* こうしてもrはiを参照し続ける */

>>622
馬鹿はだまってろ

625 名前:デフォルトの名無しさん :2005/11/06(日) 20:15:08
>>624
まあ餅付けよ
実際に自分で試すのは大事なことだと思うぞ

626 名前:デフォルトの名無しさん :2005/11/06(日) 20:16:04
>>625
同意。自分で試さないからrなんていう未定義変数を使っちゃうんだよな。

627 名前:デフォルトの名無しさん :2005/11/06(日) 20:16:50
あ、r経由でrの参照先を書き換えることはできないって言ってるのか。
失礼しました。

628 名前:616 :2005/11/06(日) 21:02:39
>>617-624
EffectiveC++買ったは良いけど読んでませんでした・・・。
みなさんこんな質問してすいません。でも、良くわかりました。ありがとうございます。

629 名前:デフォルトの名無しさん :2005/11/07(月) 01:51:40
>>628
EffectiveC++は一種の思想書だから、他の本の方がいいかも

630 名前:デフォルトの名無しさん :2005/11/07(月) 02:17:46
C++って今のところ正規表現サポートしてないですよね?
このあたり、厳しいかと思うのですが、標準サポートの
動きはないのでしょうか。

631 名前:デフォルトの名無しさん :2005/11/07(月) 02:27:08
とっくの昔にあるにょ
次の規格改定で入る予定だにょ
それまで待てないんだったらboostでググってみろにょ

632 名前:デフォルトの名無しさん :2005/11/07(月) 02:31:09
x |= 0x01
これと逆で、あるビットを0にする演算子なにですか?

633 名前:デフォルトの名無しさん :2005/11/07(月) 02:36:50
x &= ~0x01

634 名前:デフォルトの名無しさん :2005/11/07(月) 02:37:18
x &= ~0x01

635 名前:デフォルトの名無しさん :2005/11/07(月) 02:37:55
x &= ~0x01

636 名前:デフォルトの名無しさん :2005/11/07(月) 02:54:34
>>633,634,635
ありがとうがざいます。

637 名前:デフォルトの名無しさん :2005/11/07(月) 03:36:57
C++でプログラム書くとなんであんなにバイナリがでかくなっちゃうの?

638 名前:デフォルトの名無しさん :2005/11/07(月) 04:22:44
-D_RTLDLLを指定しているかい?

639 名前:デフォルトの名無しさん :2005/11/07(月) 04:28:59
delphiとかvbに比べたら小さいと思うが

640 名前:デフォルトの名無しさん :2005/11/07(月) 05:53:59
>>638
>>13

>>14
>>24
>>25

641 名前:デフォルトの名無しさん :2005/11/07(月) 06:16:06
逆に言えはなんでCはあんなにバイナリが小さいのか。
やっぱりCこそ最強にバランスの取れたプログラミング言語なのか。

642 名前:デフォルトの名無しさん :2005/11/07(月) 07:13:34
>>637,641
「あんなに」って言われてもわかんねぇぞ。

643 名前:デフォルトの名無しさん :2005/11/07(月) 07:26:45
STLつかうと一気に実行ファイルサイズが10倍に?!

644 名前:デフォルトの名無しさん :2005/11/07(月) 07:57:31
>>624
>r = j; /* こうしてもrはiを参照し続ける */
vc7.1は普通にjを参照するけど。
ttp://www.kuzbass.ru/docs/isocpp/decl.html#dcl.ref
にはそういうことは記述されてないけど。

645 名前:デフォルトの名無しさん :2005/11/07(月) 08:01:05
>>644
> vc7.1は普通にjを参照するけど。
それがほんとで assert(&r == &j) が通るなら VC7.1 は盛大にバグっていることになるが、
そんな話は聞いたこと無いのでおそらくお前がバグってるんだろう。

646 名前:デフォルトの名無しさん :2005/11/07(月) 08:17:11
>>643
STL使って実行ファイルの サ イ ズ が増えたとしても
何の影響もない。今時ハードディスクでヒィヒィ言う奴なんていないだろ。
それよりも開発が楽になることの方が素晴らしい。
STLマンセー

647 名前:デフォルトの名無しさん :2005/11/07(月) 09:02:17
>>646

648 名前:デフォルトの名無しさん :2005/11/07(月) 09:35:05
>>644
値とオブジェクトを取り違えてないか?

int i = 1, j = 2;
int& r = i;
std::cout << r << std::endl; // rの参照先はiで、iは1だから1が出力される
r = j; // rの参照先はiのままで、jの「値」である2が代入される
std::cout << r << std::endl; // だから、ここで2が出力される
std::cout << i << std::endl; // これも2
r = 3; // rの参照先はiのままだから、この文はiに3を代入する
std::cout << r << std::endl; // 3が出力される
std::cout << i << std::endl; // これも3
std::cout << j << std::endl; // jはrとは無関係、従って2が出力される


649 名前:644 :2005/11/07(月) 10:43:07
>>645,648
ごめんアホでした。言い訳をしたいけど止めときます。(´・ω・`)ショボーン

650 名前:デフォルトの名無しさん :2005/11/07(月) 11:01:01
>>649
どうせだから聞かせてくれ。参照を理解できない香具師に教えるヒントになるかも知らん。

651 名前:デフォルトの名無しさん :2005/11/07(月) 11:09:01
>>646
プ

652 名前:デフォルトの名無しさん :2005/11/07(月) 11:44:56
>>650
いや、たいした理由じゃないけど勘違いしてた。それも、まじめに。

int& r=a;
は初期化するときaの参照先を受け取るから
r=b;
代入してもそれはbの参照先を受ける

というよなプロセスで勘違いしてた。

653 名前:デフォルトの名無しさん :2005/11/07(月) 11:56:52
>>652
レスTHX。
なるほど、ありがちとは言え、判っている人間は思いつかないような落とし穴だね。

654 名前:デフォルトの名無しさん :2005/11/07(月) 14:19:04
int& r = &a;
こういう方が直感的に?

655 名前:デフォルトの名無しさん :2005/11/07(月) 14:56:00
>>654
( ゚Д゚)ハァ?

656 名前:デフォルトの名無しさん :2005/11/07(月) 14:57:36
つくづくCのポインタ表記はまぎらわしいと思うな。
引数と宣言と代入で意味が混ざる。

int instance;
int* pointer = &instance;
int& reference = instance;

void function(int by_value, int* by_pointer, int& by_reference) {
 int instance_by_value = by_value;
 int instance_by_pointer = *by_pointer;
 int* pointer_by_pointer = &by_pointer;
 int instance_by_reference = by_reference;
}


657 名前:デフォルトの名無しさん :2005/11/07(月) 14:58:38
>>656
訳の分からんPascalのポインタよりマシだろ

658 名前:デフォルトの名無しさん :2005/11/07(月) 15:24:08
テンプレートライブラリを使うとなんであんなにバイナリがでかくなってしまうのか。
アセンブリソース眺めて調べないと。マンドクセ。

659 名前:デフォルトの名無しさん :2005/11/07(月) 15:33:19
>653
それは、判ってないんじゃないかと思う。
実際、r=b;がどちらが参照するかは状況による。
俺も、判っているとは言えない。

660 名前:デフォルトの名無しさん :2005/11/07(月) 15:43:15
判ってないからこそ、必ず、直後にアドレスを確かめる、
元の値をホーチしたまま、アドレスが変わったほうが参照した側だ。

661 名前:デフォルトの名無しさん :2005/11/07(月) 16:25:42
個人的にはポインタの宣言する時に
int *pとかではなく
int* p、もしくは、(int*)pとすると
気持ち見やすいと思う

662 名前:デフォルトの名無しさん :2005/11/07(月) 16:34:56
>>661
それすると int *ptr, var;としたいときに
int* ptr, var;となってわかりにくくなる

663 名前:デフォルトの名無しさん :2005/11/07(月) 16:36:05
それはそうだが、その前にそんな宣言しないよなぁ

664 名前:デフォルトの名無しさん :2005/11/07(月) 16:41:03
一行一宣言

665 名前:デフォルトの名無しさん :2005/11/07(月) 16:42:11
すくなくともintとintのポインタの宣言は分けるべきだろう

666 名前:デフォルトの名無しさん :2005/11/07(月) 16:44:54
>>>661
(int*)pは文法違反。(int (*p)は問題ない)
ちゃんと統一的な規則があるんだから、宣言を
型名 変数名;
と考えるのはやめた方が合理的だと思う。

667 名前:デフォルトの名無しさん :2005/11/07(月) 16:55:47
LPINTでいいじゃん

668 名前:デフォルトの名無しさん :2005/11/07(月) 17:00:18
int* p;
のほうが合理的のような気がする。。。

669 名前:デフォルトの名無しさん :2005/11/07(月) 17:02:12
LPINT<=>int*
であることを考えると、
int* p;
だな。
int *p;
だと*pが変数名?みたいな感じでキモイ。

670 名前:デフォルトの名無しさん :2005/11/07(月) 17:15:52
>>669
Cジジイは黙っちゃいないよ

671 名前:デフォルトの名無しさん :2005/11/07(月) 17:16:43
ここでお約束のこれ

int *p;と書くと式の中で*pと書けばint値が得られると読める。

672 名前:デフォルトの名無しさん :2005/11/07(月) 17:40:07
int * p;

673 名前:デフォルトの名無しさん :2005/11/07(月) 17:43:38
int
*
p
;

674 名前:デフォルトの名無しさん :2005/11/07(月) 18:02:29
int* ^p^;

675 名前:デフォルトの名無しさん :2005/11/07(月) 18:47:12
実際exeバイナリのサイズが問題になる状況でC++なんて使ってられるのか?
>>646はWin32環境の事しか考えてなさそうだが。

676 名前:デフォルトの名無しさん :2005/11/07(月) 18:50:44
>>675
C++の方が可読性を維持したまま実行モジュールサイズを削減できる可能性が高いと思うが。
#コンテナクラスやstd::stringを使いまくったらワヤだけど。

677 名前:デフォルトの名無しさん :2005/11/07(月) 19:02:47
>>671
>*pと書けばint値が得られると読める。

そう読むと、既にメモリが確保されているかのような誤解を招く。

678 名前:デフォルトの名無しさん :2005/11/07(月) 19:09:12
それは型と値の区別ができていないわけで。

679 名前:デフォルトの名無しさん :2005/11/07(月) 19:25:13
恋愛と結婚の区別ができません

680 名前:デフォルトの名無しさん :2005/11/07(月) 19:27:11
>>675
バイナリのサイズが問題になるような使い方をしなければ
C++でもまったく問題無いでしょう。
C++はそう作ろうと思えばそう作れる言語ですから。
(それができないのは、できない人間の能力の問題ですし)

681 名前:デフォルトの名無しさん :2005/11/07(月) 19:28:44
>>676
俺と同郷の北海道人だろ

682 名前:デフォルトの名無しさん :2005/11/07(月) 19:44:15
関数にデータを渡すときに
func(const std::vector<XXX> & data)
みたいなコンテナむき出しの渡し方はダサイですか(´・ω・`)

<algorithm>のようにイテレータで渡したいんだけど・・・

683 名前:デフォルトの名無しさん :2005/11/07(月) 19:53:05
>>682
> <algorithm>のようにイテレータで渡したいんだけど・・・
それならイテレータで渡せばいいんじゃないかな?

684 名前:デフォルトの名無しさん :2005/11/07(月) 19:53:46
>>653
おめー、ム板のマルチスレッドスレにも居ただろ?
ここでも丸投げかよ。

685 名前:デフォルトの名無しさん :2005/11/07(月) 20:16:19
>>682
typedefとか!

…だめ?

686 名前:デフォルトの名無しさん :2005/11/07(月) 20:28:37
>>685
詳細キボン

687 名前:デフォルトの名無しさん :2005/11/07(月) 20:30:37
#define iVector std::Vector<int>
とかでもいけるんでないの?

688 名前:デフォルトの名無しさん :2005/11/07(月) 20:30:53
>>686
詳細ってtypedefがわかんないの??
それより682で言ってるようにイテレータでわたしゃいいじゃん

689 名前:デフォルトの名無しさん :2005/11/07(月) 20:32:43
>>687
いけるいけない以前になぜtypedefでなくdefineなのかと?
それからなぜVが大文字なのかと?

690 名前:デフォルトの名無しさん :2005/11/07(月) 20:33:03
>>687
せめて
typdef std::Vector<int> iVector;

691 名前:デフォルトの名無しさん :2005/11/07(月) 20:40:29
イテレータで渡すなら:
template <typename Iter>
void func(Iter first, const Iter& last) {
 while (first != last) {
  ++first;
 }
}
みたいにすればいいんじゃないの。
コンテナがよければ:
template <typename Container>
void func(Container& c) {
 typedef typename Container::iterator Iter;
}


692 名前:デフォルトの名無しさん :2005/11/07(月) 20:44:55
未だにイテレータの有効期間が分からない俺ガイル。
コンテナの要素に対して変更が行われない限りは使い回していいのかな?

693 名前:682 :2005/11/07(月) 21:03:40
皆さんありがとう。大変勉強になります (・ω・)シャキーン

694 名前:デフォルトの名無しさん :2005/11/07(月) 21:04:59
>>691
682は普通の関数作りたいだけじゃないのか?

695 名前:デフォルトの名無しさん :2005/11/07(月) 21:44:09
すいません、ちょっとアイデアを頂きたいのですが・・・

int型整数をLPSTR型文字列に変換する手順てなにかないでしょうか?

696 名前:デフォルトの名無しさん :2005/11/07(月) 21:50:33
>>695
そのint型の変数をnとするとboost::lexical_cast<std::string>(n).c_str()とすればよい。
標準ライブラリだけでやりたいのならstd::ostringstreamを活用する。
まあstd::sprintfもなくはないけど……。


697 名前:デフォルトの名無しさん :2005/11/07(月) 23:04:24
LPSTR型って何?


698 名前:デフォルトの名無しさん :2005/11/07(月) 23:07:59
>>697
MSDN嫁

699 名前:デフォルトの名無しさん :2005/11/07(月) 23:08:28
LPINT型整数

700 名前:デフォルトの名無しさん :2005/11/07(月) 23:12:45
>692
vector/dequeはコンテナに対して要素の追加時と削除時に無効になる。
list/map/setはイテレータの指す所が削除されたときに無効になる。

unordered_map/setはどうなるんだろうね?


701 名前:デフォルトの名無しさん :2005/11/07(月) 23:12:49
typedef CHAR* LPSTR;

702 名前:650=653 :2005/11/07(月) 23:26:01
>>684
どこがどう丸投げだと?

703 名前:デフォルトの名無しさん :2005/11/07(月) 23:37:45
>>700
トンクス!

704 名前:デフォルトの名無しさん :2005/11/08(火) 00:00:02
>>696
回答ありがとうございました
なるべくなら標準ライブラリでやりたいのですが・・・
その先の活用の仕方が思いつきません orz

どうか教えていただけないでしょうか?

705 名前:デフォルトの名無しさん :2005/11/08(火) 00:03:59
>>704
めんどくさいから、char buf[20]; int num = 100; std::sprintf(buf, "%d", num);とでもしとき。

706 名前:デフォルトの名無しさん :2005/11/08(火) 00:13:37
>>704
俺もよく分かってないから間違ってるかも知れんが
ostringstreamに出力させた後で、一時的なstringオブジェクト作って
そいつにostringstream.str()で移して、c_str()使えばいいんじゃね?

707 名前:デフォルトの名無しさん :2005/11/08(火) 01:08:48
>>704
#include <sstream>

int num = 12345;
std::ostringstream oss;
oss << num;
oss.str().c_str(); // ←これを使う。

708 名前:デフォルトの名無しさん :2005/11/08(火) 01:32:56
sprintfの方が高速だからこっちのがいいと思うが・・

709 名前:デフォルトの名無しさん :2005/11/08(火) 02:03:43
CBaseClassから派生したCMyClassを作っています。
両方ともテンプレートでCMyObjクラスを指定してあげます。
CBaseClassはLibにして、CMyClassはAPのほうで実装します。
しかしCBaseClassのメソッドを呼び出すとリンクエラーになります。
よく見るとLibファイルにCBaseClassのメソッドが出力されてません。

ソースは以下のようです。
ライブラリを使うアプリ
//App.cpp
template <class T> CMyClass : public CBaseClass<T>
{
};
CMyClass<CMyObj> m_MyClass;
m_MyClass.Foo();

ライブラリ
//BaseClassLib.cpp
template<classs T> CBaseClass
{
public:
 CBaseClass(){};
 ~CBaseClass(){};
 void Foo(){printf("foo\n");}
};

というつくりなのですが、CBaseClassのメソッドはBaseClassLib.libに出力されないのですか?


710 名前:デフォルトの名無しさん :2005/11/08(火) 02:11:38
>>709
テンプレートは型が確定しないと実態を作れないので、ライブラリ化できません。

711 名前:デフォルトの名無しさん :2005/11/08(火) 02:12:24
>>709
キーワードを教えてやるよ。
テンプレート リンクエラー 定義
あとは自分で考えな。

712 名前:デフォルトの名無しさん :2005/11/08(火) 02:32:18
>>710
ありがとうございます。やっぱりそうなのか。。


713 名前:デフォルトの名無しさん :2005/11/08(火) 03:19:56
class A{
B obj_b;
C obj_c;
};

class B{
int hogehoge;
}

class C{
int gehogeho;
}

というAがクラスBとクラスCのオブジェクトをもつとします。
Aの要素としてBからC、CからBのようなアクセスをしたいんですがどうしたらいいでしょうか。

714 名前:デフォルトの名無しさん :2005/11/08(火) 03:39:59
設計を見直す。

715 名前:デフォルトの名無しさん :2005/11/08(火) 04:01:53
>>713
B、Cそれぞれのpublicメンバなら普通に触れるでしょ
なにが問題なの?

716 名前:デフォルトの名無しさん :2005/11/08(火) 04:14:12
obj_bからobj_cのメンバ変数ってどうやって指定するのですか?

717 名前:デフォルトの名無しさん :2005/11/08(火) 05:05:39
>>710
.NET2.0だとテンプレートのままライブラリ化できるんだっけ?

718 名前:デフォルトの名無しさん :2005/11/08(火) 05:10:08
>>716
何がしたいのかよく判らんのだが
無茶なことを考えているらしいということだけは判った
あきらめて寝ろ
目が覚めたら一から勉強しなおせ

719 名前:デフォルトの名無しさん :2005/11/08(火) 05:20:37
class B内にclass Cへのポインタをメンバに含めればいいでしょ

class C;

class B{
public:
int hogehoge;
C* lp_obj_c;
};

みたいにして、lp_obj_cを介してobj_cのメンバ変数にアクセスする
当然だがあらかじめlp_obj_cにclass A内のobj_cへのポインタを代入しとかないとだめ

720 名前:デフォルトの名無しさん :2005/11/08(火) 09:42:12
リング形式?のコンテナクラスってありますか?
イテレータを++していって最後まで行ってら自動的に先頭まで戻って、
使う側からしたら永遠にデータを取り出せるような奴。

721 名前:デフォルトの名無しさん :2005/11/08(火) 10:08:39
とりあえず標準にはないですな。

722 名前:デフォルトの名無しさん :2005/11/08(火) 10:12:43
>>720
それって標準コンテナの要件満たすのか?
end で何を返すの?

723 名前:デフォルトの名無しさん :2005/11/08(火) 10:15:03
というか
if (it == hoge.end()) it = hoge.begin();
をループに入れるだけで実現できると思うんだが

724 名前:デフォルトの名無しさん :2005/11/08(火) 10:17:24
end()が意味を為さないね。
リングバッファはしばしば使うけど、固定長だから自力で実装しているなぁ。

>>720
大した手間じゃないから、標準コンテナのI/F見ながら自分で作ってみよう。

725 名前:720 :2005/11/08(火) 10:31:23
一般的なものはないというのはわかりました。ありがとう。
>>723
それをいれないでグルグルアクセスできたら少しきれいになるかなと
思ったので。

726 名前:デフォルトの名無しさん :2005/11/08(火) 10:44:19
>>725
だからそれをやるクラスを作ればいいじゃん。
>724は非コンテナって言ってるけどvectorで実装すれば>723をそのまま内部で持てばいい。
単なるリングバッファならend()も要らなきゃbegin()も要らぬ。operator[]があればいい。

727 名前:デフォルトの名無しさん :2005/11/08(火) 11:27:27
>>692
ローカル変数の使いまわしはバグの基
基本に返って関数分けを考えたほうがヨロシ

728 名前:デフォルトの名無しさん :2005/11/08(火) 11:42:12
>>726
> >>725
> だからそれをやるクラスを作ればいいじゃん。

別に作りたくないとは言ってないけど、何か誤解されてる?


729 名前:デフォルトの名無しさん :2005/11/08(火) 12:05:45
720 が言ってるのはそういうものでスタンダードなのがあれば教えてくれってことでしょ

730 名前:デフォルトの名無しさん :2005/11/08(火) 12:12:37
あの。質問です。下のコードがコンパイルエラーになるのですが・・
ローカルクラスオブジェクトは std::for_each() などのファンクタに
指定することはできないのでしょうか?

#include <iostream>
#include <vector>

int main( void) {
 struct F {
  void operator()(const int & i) const {
   std::cout << i << std::endl;
  };
 };
 std::vector<int> vec;
 vec.push_back(100);
 vec.push_back(200);
 std::for_each(vec.begin(),vec.end(),F());
 return EXIT_SUCCESS;
}

731 名前:デフォルトの名無しさん :2005/11/08(火) 12:23:26
>>730
はい


732 名前:デフォルトの名無しさん :2005/11/08(火) 12:27:48
>>730
ローカルに拘るんだったら以下のようにどうぞ
int main( void) {
- struct F {
- void operator()(const int & i) const {
+ struct Local {
+ static void F (const int & i) {
std::cout << i << std::endl;
};
};
std::vector<int> vec;
vec.push_back(100);
vec.push_back(200);
- std::for_each(vec.begin(),vec.end(),F());
+ std::for_each(vec.begin(),vec.end(),&Local::F);
return EXIT_SUCCESS;
}


733 名前:730 :2005/11/08(火) 12:28:30
無理でした。orz

>14.3.1 Template type arguments
>2 A local type, a type with no linkage, an unnamed type or a type compounded from
>any of these types shall not be used as a templateargument for a template
>typeparameter.

>>731
ありがとうございます。

734 名前:730 :2005/11/08(火) 12:37:16
>>732
なるほど・・トリッキーな手法ですね。勉強になります。
ありがとうございました。

735 名前:デフォルトの名無しさん :2005/11/08(火) 12:59:02
>>709
一応、標準にはある仕様ってことで
ライブラリ側のクラス定義にexportキーワードを指定すればいいことになってるおw

736 名前:デフォルトの名無しさん :2005/11/08(火) 13:58:25
>>700
>unordered_map/setはどうなるんだろうね?
今の予定では insert メンバが呼ばれると無効化されるかもしれない,という仕様です.
ただし要素への参照やポインタの有効性は,その要素が削除されるまで常に維持されます.
また,load factor と bucket count の値から iterator が無効化されるかどうかを
事前に知ることができますし,rehash や max_load_factor を用いて
iterator が無効化されるタイミングをある程度調節することが可能です.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1745.pdf>>720

>>720
boost-sandbox に circular buffer があります.参考までに.

>>732
これはあくまで関数ポインタ経由のコールバックなので,関数オブジェクトに比べて
インライン化が効きにくくなるという状況はあるでしょうね.

737 名前:デフォルトの名無しさん :2005/11/08(火) 19:39:11
template<class T>struct Hoge
{
 T* t;
 Hoge(int n){ t = new T[n]; }
};
assert(Hoge<int>(10).t[0] == 0);

↑Tにプリミティブ型を入れたときにtの各要素を初期化する方法ってありますか?
T()を代入するのは非プリミティブ型のときにコストがかかるし・・・
全てのプリミティブ型に対して特殊化するのはスマートではないし・・・

738 名前:デフォルトの名無しさん :2005/11/08(火) 19:48:06
>>737
すぐ思いつくのは、
・std::uninitialized_fillを使ってT()で初期化する
・boostのtype_traitsで組み込み型を判別する

739 名前:デフォルトの名無しさん :2005/11/08(火) 20:09:09
>>738
ありがとうございます。
いずれもtype traitsですね。パクってみます。

740 名前:デフォルトの名無しさん :2005/11/09(水) 12:17:21
->*
.*
これらはどういうものなんでしょうか?

741 名前:デフォルトの名無しさん :2005/11/09(水) 13:11:27
>>740
「メンバへのポインタ演算子」でググレ

742 名前:デフォルトの名無しさん :2005/11/09(水) 13:26:50
>>741
thx

743 名前:デフォルトの名無しさん :2005/11/09(水) 16:33:52
newって何のためにあるんでしょうか?
「newで生成したオブジェクトはポインタのスコープに関係なく存在するから」
みたいな説明がありますが、スコープに関係ないってのよくないですよね?
理解に苦しみます。

744 名前:デフォルトの名無しさん :2005/11/09(水) 16:47:12
>>743
>スコープに関係ないってのよくないですよね?
いいや。

745 名前:デフォルトの名無しさん :2005/11/09(水) 16:49:22
auto_ptr

746 名前:デフォルトの名無しさん :2005/11/09(水) 16:54:50
newが無かったら
不定値な領域を確保したいときはどうするんだ?

747 名前:デフォルトの名無しさん :2005/11/09(水) 18:41:29
>>743
vtblがあるようなオブジェクトを実体化させる時困る。


748 名前:デフォルトの名無しさん :2005/11/09(水) 18:54:14
なくても困らないよ。newなんてシンタックスシュガーだよ。

749 名前:デフォルトの名無しさん :2005/11/09(水) 19:19:36
なんだか甘そうだな

750 名前:デフォルトの名無しさん :2005/11/09(水) 19:38:25
>>747
おそらく743はmallocとの違いを聞いているのではないと思う。


■過去ログ置き場に戻る■ 1- 前250 次250 最新50
DAT2HTML 0.33f Converted.