C++相談室 part17
■ このスレッドは過去ログ倉庫に格納されています
0001v(^・^)v
NGNGただし質問の前にFAQに一通り目を通してください。
また、テンプレートライブラリ(STL含む)に関する質問は
専用の別スレへどうぞ。
過去スレ、関連スレ、関連リンクなどはこちら>>2-15
0233名無しさん
NGNG0234デフォルトの名無しさん
NGNG0235デフォルトの名無しさん
NGNG0236デフォルトの名無しさん
NGNGノ∩
⊂ ヽ ←>>233
/( 。Д。 )っ
U ∨ ∨
・@;∴‥
∧_∧ ∩ :: :.
( ・∀・)/ :: ::
(つ / :: :'
人⌒l ノ :: :: ガッ
し(_)
0237デフォルトの名無しさん
NGNGこれ、良いんじゃね?
0238名無しさん@Emacs
NGNGそれ何?説明読んだけどイマイチ分からんかった。
C++の文法を拡張した物のC++へのトランスレーターって事?
0239デフォルトの名無しさん
NGNG・fを呼び出す
・fのアドレスを取る
の2つだけである、ってのは正しいかな?
0240228
NGNGnamespace myns {
class Class1 { ... };
swap(Class1 &x, Class1 &y) throw();
...
namespace junk {
using std::swap;
}
template <class Iter> void foo(Iter s, Iter e) {
using namespace junk;
Iter i1, i2;
...
swap(*i1, *i2);
}
}
なんて絶対やりたくないんだけど。
やっぱりオーバーロードしようとするのが間違い?
0241230
NGNG俺は常に.cppの頭でusing namespace std;する人なので
それは考えたことがなかった。。。けど、そんな複雑にせんでも
template <class Iter> void foo(Iter s, Iter e) {
using std::swap;
Iter i1, i2;
...
swap(*i1, *i2);
}
だと何か問題あるのか?
0242デフォルトの名無しさん
NGNGすまん書き間違えた...
×: エラーコードがスレッド毎に保存されることぐらい常識だと思うが...。
○: (マルチスレッドを考慮に入れるなら) エラーコードをスレッド毎に保存することぐらい常識だと思うが...。
まさかやり方知らないとか ?
0243デフォルトの名無しさん
NGNGリフレクションが使えるC++
0244デフォルトの名無しさん
NGNGgccだとどうやるの?
0245デフォルトの名無しさん
NGNG0246228
NGNGそれだとmyns::swap()が見えない。
ちなみに単にswap()だけ、あるいはusing namespace stdだと、
*i1,*i2がprimitive型の時にstd::swap()が見えなくなる。
0247デフォルトの名無しさん
NGNGだからメンバ変数だっていってんだろ!!
オブジェクト一つずつにそんなことする気か?
>threadハンドルをキーにmapする。
これじゃ足りねーよ
0248デフォルトの名無しさん
NGNGスレッドは C++ の標準じゃねーから、単に gcc と書かれても困る。
0249デフォルトの名無しさん
NGNG0250デフォルトの名無しさん
NGNGJavaだったらスタティックイニシャライザでクラスに属するリソースの初期化処理をやりますよね。
でも、C++では言語としてそのような機能はないみたい(あるのかも知れないが、私は知らない)。
そこで、以下のようにグローバル変数で初期化しているのですけど、
namespace _hoge {
pthread_mutex_t mutex;
class Initializer {
public:
Initializer(){
pthread_mutex_init(&mutex, NULL);
}
};
Initializer initializer;
};
なんかダサい気がします。もっとよい方法を識者の方に伺いたいです。
(ちなみに、mutexをクラスのメンバにしてPTHREAD_MUTEX_INITIALIZERで初期化すると
「インテグラルじゃない値を初期化しようとしてる」みたいな警告が出るのでもっとダサい)
0251デフォルトの名無しさん
NGNG二回目以降はスキップ。
ダサいのがいやならカエレ!
0252デフォルトの名無しさん
NGNGpthread_mutex_t を、initするクラスでラップしといてから
template<class T>
inline CMutex& common_mutex_of() {
static CMutex mutex;
return mutex;
}
0253250
NGNGコンストラクタ内で初期化する方法だと、mutexを初期化するのは、メインスレッド
でやらないと駄目。でもメインスレッドから hoge::init() みたいなのを呼ぶのはダサい(呼び忘れるから)。
で、コンパイル時か、実行時でもmain関数より前に初期化を行いたい。
0255デフォルトの名無しさん
NGNGほら
pthread_mutex_t mutex;
bool pinit(){ pthread_mutex_init(&mutex, NULL); return true; }
bool pinitialized=pinit();
これでどうよ?
0256デフォルトの名無しさん
NGNGそれ一般的に使われてんの?
学究的な興味なんざ小指の爪の先ほどもない。
職業プログラマとして必要な技術?
0257デフォルトの名無しさん
NGNG0258250
NGNGあ、それでいいのか。
でもやっぱグローバル変数使わざるを得ない?
staticなメンバ変数と関数だけで済ませられないでしょうか。
(駄目なら、グローバル変数での初期化が定石ってことでいいのでしょうか)
>>256
標準ライブラリで使われている気が、、、
0259デフォルトの名無しさん
NGNGstaticなメンバ変数はほとんどグローバル変数と同じようなもんだぞ?
0260デフォルトの名無しさん
NGNGうーむ、ぐぐっても解説等出てこないから比較的新しい技術なのかと思っていたが、
C++の標準的な「何か」なのかな・・・
CからC++へ、なんとなく体で移行してきたんでわからんことが大杉。
本腰入れて勉強しないと限界みたい・・・
0261デフォルトの名無しさん
NGNGさてどうする?
0263デフォルトの名無しさん
NGNG無名ネームスペースに閉じ込めたら?
0264デフォルトの名無しさん
NGNG正しくない。
意味のある使い方がまだある。
0265250
NGNGなるほど。っていうか、無名namespaceってのは初めて知りました。
mutex を、それを利用するクラスのメンバにして、
初期化は無名namespaceのグローバル変数を使ってやると。
それが一番かもしれないですね。
0266名無しさん
NGNGるいじの質問もあるし…
ぽんと,いい考えがうかばないのか?
0267デフォルトの名無しさん
NGNGそういう人はとっくにC#に以降済みだし。
0268デフォルトの名無しさん
NGNG( ・∀・) | | ガッ
と ) | |
Y /ノ 人
/ ) < >__Λ∩
_/し' //. V`Д´)/
(_フ彡 / ←>>266
0269デフォルトの名無しさん
NGNG0270デフォルトの名無しさん
NGNGユーザー定義型を使って標準ライブラリのテンプレートを特殊化することは認められている。
17.4.3.1 -1- (ttp://www.kuzbass.ru/docs/isocpp/lib-intro.html#lib.reserved.names)
オーバーロードの追加が認められているという記述は見当たらなかった。
0272デフォルトの名無しさん
NGNGテンプレートライブラリを作成するときにstd::swap(a,b)を使うことを考えると、
自前のswap処理を作ったならstd::swapの特殊化をしておくべきだと思うんだが、
boost::scoped_ptrなんかは、boost::swapが定義されてるな。
これだと、
scoped_ptr<T> a,b;
std::swap(a,b);
と書いても、a.swap(b)にはならないな。
0273272
NGNG↑によると、
namespace std
{
template<typename T>
class X {};
template<typename T>
void swap(X<T>& rhs, X<T> lhs);
}
これは特殊化ではなく、オーバーロードの宣言になるので、規格違反になるそうだ。
結果として、
自前のクラスについてstd::swap等の特殊化はできるが、
自前のクラステンプレートについては(規格に従う限り)不可能らしい。
0274デフォルトの名無しさん
NGNGその static なデータメンバの定義を行っても、リンク時に一つにまとめられてしまうよう
なのですが、これは規格に則った動作でしょうか。
-- X.h --
template<class T> class X {
static T x;
};
template<class T> T X<T>::x;
-- Foo.cpp --
#include "X.h"
void foo()
{
X<int> a;
}
-- Hoge.cpp --
#include "X.h"
void hoge()
{
X<int> b;
}
ここで Foo.cpp と Hoge.cpp をコンパイルしてリンクしても、とくに X<int>::x の
多重定義にはならず、正常にリンクされます。(g++ と VC++ で確認)
しかし、C++第3版の 13章7節によると「非inline の static メンバは、どこかの翻訳単位に
ユニークな定義を持たなければならない。」とあり、上のような動作は保証されていない
ようなのです。
0275デフォルトの名無しさん
NGNG14.5.1.3にX.hの内容と同じ例があげられている。
その挙動を疑うなら、以下のソースも疑うことになると思うのだが・・・。
-- X.h --
template<class T>
void f();
-- Foo.cpp --
#include "X.h"
void foo()
{
f<int>();
}
-- Hoge.cpp --
#include "X.h"
void hoge()
{
f<int>();
}
0276275
NGNG-- X.h --
template<class T>
void f(){}
0277デフォルトの名無しさん
NGNG0278デフォルトの名無しさん
NGNGを元に戻すテーブルかなにかはありませんか?
0279デフォルトの名無しさん
NGNGWinならUnDecorateSymbolNameというのがある
0280デフォルトの名無しさん
NGNG?HogeHoge@@YAHG@Z == int __cdecl HogeHoge(unsigned short)
0281278
NGNGすばらしいですぞ、このような時間に!!!
はげしくあげしく、感謝します。
0282デフォルトの名無しさん
NGNGこういう場合は、2つのクラスを、同じヘッダにまとめるしか無いのでしょうか?
----------------A.h
#ifndef A_H
#define A_H
#include "B.h"
class A(){
A( B* b );
};
#endif
----------------B.h
#ifndef B_H
#define B_H
#include "A.h"
class B(){
B( A* a );
};
#endif
----------------
0283デフォルトの名無しさん
NGNG#ifndef A_H
#define A_H
#include "B.h"
class B;
class A(){
A( B* b );
};
#endif
----------------B.h
#ifndef B_H
#define B_H
#include "A.h"
class A;
class B(){
B( A* a );
};
#endif
----------------
0285デフォルトの名無しさん
NGNGint x=0;
int *a = &++x; // OK
int *b = &x++; // エラー
bの初期化でエラーになるのはなぜでしょうか?
コンパイラによれば'&'に左辺値がないとのことですが・・・。
自分のイメージとしてはxのアドレスでbを初期化した後、
xをインクリメントするという感じなのですが・・・。
0286デフォルトの名無しさん
NGNG0287デフォルトの名無しさん
NGNGエラーですよ
0288デフォルトの名無しさん
NGNG下は&xが評価された後にインクリメントされるから、
一時領域のインクリメントはできないのか、あいまいさではじかれてるのかどっちかでしょう。
エラーコードを見ればどっちかわかる。
0289285
NGNG動かせるかではなく、なぜエラーになるのかです。
結合順位からいえば、もともとインクリメント演算子の方が強いのですが・・。
0290デフォルトの名無しさん
NGNG>論理的に可能であれば、左辺値の被演算子を取る演算子の処理結果は、
>その左辺値被演算子を示す左辺値になる。
(略)
>int *p = &++x; // p は x を指す
>int *q = &(x++); // エラー: x++は左辺値(xに格納されている値)ではない
x に副作用が発生するタイミングは前置でも後置でも ; に至るまでの
いつかでしかないと思うのだけど前置のみ左辺値になるのはどうして
だろう。
0291デフォルトの名無しさん
NGNGまあ ++x は、極論すれば、{x = x + 1, x} と同じだからアドレスがとれる。
でも、x++ は、{(x = x + 1)} と言う式になるから、アドレスが取れない。
0292デフォルトの名無しさん
NGNG0293285
NGNGあくまで&に対する左辺値が無いということが原因みたいですね。
ちなみに
int *r = &(x += 1); // OK
これはOKでした。これが前置と同じことなんですかね・・・。
後置だとカッコの中身が先に評価されないとか(超適当)。
0294デフォルトの名無しさん
NGNG0295デフォルトの名無しさん
NGNG前置の場合 x の副作用が式の評価前に行われるのは保証されてるの?
0296デフォルトの名無しさん
NGNGa = 0;
b = a++;
c = ++a;
bは0、aは1になるのはわかってんだよね?
0297デフォルトの名無しさん
NGNG○ bは0、cは1
0298デフォルトの名無しさん
NGNGこのままじゃcは2になるやん。
まぁ雰囲気だけ味わってくれ・・鬱だ死のう。
0299デフォルトの名無しさん
NGNG0300デフォルトの名無しさん
NGNGint  operator++(int&,int);
int  x = 0;
int* a = &(operator++(x));
int* b = &(operator++(x,0));
0301デフォルトの名無しさん
NGNGT operator++(int) { T temp=m_nakami; m_nakami+=1; return temp; }
後者の返り値は値(一時変数だから参照を返せない)だから
アドレスがとれないってことじゃなくて?
0302デフォルトの名無しさん
NGNG得ないということ? template とか。本末転倒な気もするけども。
0303デフォルトの名無しさん
NGNG0304デフォルトの名無しさん
NGNG0305デフォルトの名無しさん
NGNG↑こんなコード、コンパイルできるようにしてもなんのメリットもないだろ。
0307デフォルトの名無しさん
NGNGだからなんなんだ?
勉強のできないやつってのは、なぜそうなるか?どういう原理なのか?
といったことにはまったく興味をしめさず、できればいい、動けばいい
的な考えなんだよな。だから応用もきかないし、所詮そこ止まりの人間。
そういう奴はベーシックでもやってりゃいい。
0308300
NGNGオーバーロード可能な演算子のシグネチャとして、
C++では演算子'++'を>>300のように定義した。
この定義には「基本型でない型の振る舞いと対称性を保つ」目的があったかもしれない。
その結果、Cではコンパイルできなかった式'&++x'はコンパイル可能になった。
ここは「コンパイル可能にせざるを得ない」という話になるだろう。
だが、'&x++'「エラーにせざるを得ない」なんて話には、どうにもつながらない。
ちなみに、300==305。
>>307
何のメリットも無いのに、Cと異なる挙動とする意味でもあるのか?
0309デフォルトの名無しさん
NGNGもし>>302の疑問が正しいのであればそもそもC言語でも駄目なのはどうしてだ?
C言語では基本型以外にoperator ++は定義できない
0310デフォルトの名無しさん
NGNGそういうこと言っているわけじゃねぇだろって
もっと一般的な話だろ(プログラムに限らずな)
0311306
NGNGCと比較すると解釈が逆になることが分かるな。
でもメリットて話だとしたら、&++x にどんなメリットがあったのか
疑問だ。Cと同じように左辺値になり得ないとしたら問題が起こる
のだろうか。
0312デフォルトの名無しさん
NGNG意味がわかりません!!メリットなんて別にないだろ!!
0314306
NGNG++x も
0315デフォルトの名無しさん
NGNGfor(int i = 0; ... ; ...)
このiのスコープもデフォルトではforブロック外だよな、.netは。
ほかにも、標準C++に沿ったコーディングでエラーにもなるし。
標準C++のコンパイラってあんの?
0316デフォルトの名無しさん
NGNG0317300
NGNG> &++x も C と同じように左辺値にならなければよかったんでは
左辺値にならないとしたらオーバーロード可能なシグネチャの定義が、
int operator++(int&)
というようなものになり、
ユーザー定義型で効率のよい実装が難しくなる。
>>310
あれ?外してた?あんた>>307か?
何を突っ込まれたのかわからない。ごめん。
0318デフォルトの名無しさん
NGNG++x ←これは左辺値になるけど
x++ ←これは左辺値じゃない
0319デフォルトの名無しさん
NGNG0320デフォルトの名無しさん
NGNGとかできてもうれしくないしな・・・
0321デフォルトの名無しさん
NGNGこうしたのかもしれないね・・・。なにを基準に決めたのか知らんけど。
0322デフォルトの名無しさん
NGNG今議論されてることって一貫性の問題?
0323322
NGNG0324デフォルトの名無しさん
NGNG読者をなやますようなコードをちりばめるね・・・。
参考書というよりは教科書チックだな。
0325デフォルトの名無しさん
NGNGエラー。
0326デフォルトの名無しさん
NGNG*++x = *++y;
こうじゃないの?
++x = y++
は何が起こるの?
0327デフォルトの名無しさん
NGNGってけっきょく???で上書きされるから
インクリメントを事前にしても意味ないんじゃ・・・。
0328306
NGNGなんだかな・・・。
0329デフォルトの名無しさん
NGNG勘違いしているだけでしょう。
0330デフォルトの名無しさん
NGNGint y = 5;
++x = y++;
cout << x << endl;
cout << y << endl;
result:
5
6
0331デフォルトの名無しさん
NGNG++xは意味がないですね
■ このスレッドは過去ログ倉庫に格納されています