C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[7]: bind1stの型宣言の書き方


(過去ログ 76 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■45079 / inTopicNo.1)  bind1stの型宣言の書き方
  
□投稿者/ kok (1回)-(2009/12/29(Tue) 02:21:45)

分類:[.NET 全般] 

文字列のある範囲の中に文字'p'がいくつあるか、もしくは文字'p'以外がいくつあるかをカウントするのにcount_if, bind1st, equal_to, not_equal_toを以下のように使いました。

#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <string>
using namespace std;

int main() {
string s("alppjaaejkappp");

printf("%d\n", count_if(s.begin(), s.end(), bind1st(equal_to<char>(), 'p')));
printf("%d\n", count_if(s.begin(), s.end(), bind1st(not_equal_to<char>(), 'p')));
}

実行結果:
5
9

上のコードのようにcount_ifへのbind1st, equal_toの渡し方は分かるのですが、bind1stを変数に入れて持ち歩きたい場合の、その変数の型宣言が分かりません。

#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <string>
using namespace std;

int main() {
string s("alppjaaejkappp");

// ???の部分がわからない
??? eq = bind1st(equal_to<char>(), 'p');
??? ne = bind1st(not_equal_to<char>(), 'p');
??? cmp = equal_to<char>();

// 文字'p'がいくつあるか
count_if(s.begin(), s.end(), eq);

// 文字'p'以外がいくつあるか
count_if(s.begin(), s.end(), ne);

char c = 'a';
// 文字cと比較関数cmpでカウント
count_if(s.begin(), s.end(), bind1st(cmp, c));
}

???の部分は、どのように書けばよいのでしょうか?

引用返信 編集キー/
■45080 / inTopicNo.2)  Re[1]: bind1stの型宣言の書き方
□投稿者/ kok (2回)-(2009/12/29(Tue) 02:26:58)
すみません。インデントし忘れたので再掲します。

文字列のある範囲の中に文字'p'がいくつあるか、もしくは文字'p'以外が
いくつあるかをカウントするのにcount_if, bind1st, equal_to, 
not_equal_toを以下のように使いました。

#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <string>
using namespace std;

int main() {
  string s("alppjaaejkappp");

  printf("%d\n", count_if(s.begin(), s.end(), bind1st(equal_to<char>(), 'p')));
  printf("%d\n", count_if(s.begin(), s.end(), bind1st(not_equal_to<char>(), 'p')));
}

実行結果:
5
9

上のコードのようにcount_ifへのbind1st, equal_toの渡し方は分かるのですが、
bind1stを変数に入れて持ち歩きたい場合の、その変数の型宣言が分かりません。

#include <algorithm>
#include <cstdio>
#include <functional>
#include <iostream>
#include <string>
using namespace std;

int main() {
  string s("alppjaaejkappp");

  // ???の部分がわからない
  ??? eq = bind1st(equal_to<char>(), 'p');  
  ??? ne = bind1st(not_equal_to<char>(), 'p');
  ??? cmp = equal_to<char>();

  // 文字'p'がいくつあるか
  count_if(s.begin(), s.end(), eq);

  // 文字'p'以外がいくつあるか
  count_if(s.begin(), s.end(), ne);

  char c = 'a';
  // 文字cと比較関数cmpでカウント
  count_if(s.begin(), s.end(), bind1st(cmp, c));
}

???の部分は、どのように書けばよいのでしょうか?

引用返信 編集キー/
■45083 / inTopicNo.3)  Re[2]: bind1stの型宣言の書き方
□投稿者/ επιστημη (2362回)-(2009/12/29(Tue) 06:09:05)
επιστημη さんの Web サイト
2009/12/29(Tue) 06:11:02 編集(投稿者)
#if マジレスすれば
  binder1st<equal_to<char>>     eq = bind1st(equal_to<char>(), 'p');
  binder1st<not_equal_to<char>> ne = bind1st(not_equal_to<char>(), 'p');
  equal_to<char>               cmp = equal_to<char>();
#elif TR1使っていいなら
  function<bool(char)>          eq = bind1st(equal_to<char>(), 'p');
  function<bool(char)>          ne = bind1st(not_equal_to<char>(), 'p');
  function<bool(char,char)>    cmp = equal_to<char>();
#elif C++0Xも許すなら
  auto                          eq = bind1st(equal_to<char>(), 'p');
  auto                          ne = bind1st(not_equal_to<char>(), 'p');
  auto                         cmp = equal_to<char>();
#endif

※ 分類はちゃんと選択してくだせ。こんなの.NETぢゃねぇ!

引用返信 編集キー/
■45089 / inTopicNo.4)  Re[3]: bind1stの型宣言の書き方
□投稿者/ 774RR (450回)-(2009/12/29(Tue) 13:02:40)
そもそも使いたい場所にインラインで詳細が書いてあるからこそコンパイラの最適化が効く+人間にも読みやすいのであって
明示的に変数を作ってしまうとぱっとしない、んだと思うが・・・

binder1st<equal_to<char> > eq(equal_to<char>(), 'p'); // のほうがいいんでないか?

引用返信 編集キー/
■45090 / inTopicNo.5)  Re[4]: bind1stの型宣言の書き方
□投稿者/ επιστημη (2363回)-(2009/12/29(Tue) 13:35:14)
επιστημη さんの Web サイト
> binder1st<equal_to<char>>eq(equal_to<char>(), 'p'); // のほうがいいんでないか?

ですよねー^^;

僕はlambdaらぶなので

function<bool(char)> eq = [](char x) { return x == 'p'; }; // 何したいのかぱっと見でわかるしー


引用返信 編集キー/
■45100 / inTopicNo.6)  Re[5]: bind1stの型宣言の書き方
□投稿者/ kok (3回)-(2009/12/30(Wed) 05:41:42)
επιστημη さん、ありがとうございました。

"マジレスすれば"の部分が欲しいものでした。
分類の選択を見落としていました。すみません。分類はC/C++です。

sgiのSTLドキュメント(http://www.sgi.com/tech/stl/)を見ながら、
型宣言の書き方を練習していたのですが、二つ質問があります。
MinGWのg++を使っています。

一つ目の質問:

ポインタ変数を介してoperator()を呼び出すとき、->記法は使えないのでしょうか?

int main() {
  equal_to<int>* p = new equal_to<int>();
  p->(1, 2);  // コンパイルエラー
  (*p)(1, 2); // コンパイルできる
}

(*p)(1, 2)はコンパイルできますが、p->(1, 2)はコンパイルできません。
operator()を呼び出すとき、->記法は使えないのでしょうか?

二つ目の質問:

equal_to<int>(), less<int>()を配列に格納する場合の型宣言はどうなりますか?

int main() {
  binary_function<int, int, bool>* ar[] = {
    new equal_to<int>(),
    new less<int>(),
  };
}

上のコードはコンパイルできますが、

(*ar[0])(1, 2)

を加えるとコンパイルエラーとなります。
配列の型宣言が間違っているのか、それともoperator()の呼び出しが間違っているのか、
そもそもequal_to<int>(), less<int>()を一つの配列の格納できないのか、
どれだが分からないのですが、以下のようなコードを書きたいです。

int main() {
  // ???の部分がわからない
  ??? ar[] = {
    new equal_to<int>(),
    new less<int>(),
  };
  
  ???* p = ar[0];
  (*p)(1, 2); // equal_to<int>()(1, 2)を呼び出す
  
  ???* p = ar[1];
  (*p)(1, 2); // less<int>()(1, 2)を呼び出す
}

774RRさん、

> binder1st<equal_to<char>>eq(equal_to<char>(), 'p'); // のほうがいいんでないか?

わからなかったのですが、タイプ数が少なくなるからですか?
たとえば、以下の二つは同じ意味(コストも同じ)だと思っていたのですが…。

struct A {
  A(int x) {}
};

int main() {
  A a(10);      // 下の行と同じ意味(コストも同じ)
  A b = A(10);  // 上の行と同じ意味(コストも同じ)
}

よろしくお願いいたします。

引用返信 編集キー/
■45102 / inTopicNo.7)  Re[6]: bind1stの型宣言の書き方
□投稿者/ 774RR (451回)-(2009/12/30(Wed) 08:10:40)
A a(10); と A b=A(10); は、言語規格書上の解釈は若干違うのでまったく同一ではない。
前者は a を直接構築しているのに対して、後者は複写によって b を構築している。
規格書の文言上、後者が成立するためにはコピーコンストラクタが必要。

class X {
 X(const X&); // non copyable
 int value;
public:
 X(int x) : value(x) {}
};

int main() {
 X a(10); // is OK
 X b=X(10); // b is copy-constructed, compile error
}
VC++6 など規格書採択前の処理系では期待通りのエラーが出ないので注意
まっとうなコンパイラであれば RVO の結果として両者とも同一のコードが生成されることになる

binary_function はそもそも operator() を持っていないので、そういう配列化はできない。
p->operator()(1,2); なら通るよ。

引用返信 編集キー/
■45111 / inTopicNo.8)  Re[7]: bind1stの型宣言の書き方
□投稿者/ kok (4回)-(2009/12/30(Wed) 14:44:17)
774RRさん、ありがとうございました。

コピーコンストラクタをprivateにすると、X b=X(10)はコンパイルできなくなるのですね。
p->operator()(1, 2)も勉強になりました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -