C#のデリゲードを
javaとC++でできないでしょうか。
ただし、質問内容を勘違いされそうなので、求めている内容と、
求めていない内容を、詳しく
書きますと。
インタフェース委譲を使った例は、求めていません。
あらかじめ、委譲先に静的に仕組みを
作っておかなく手も、C#のデリゲードのように、シグニチァが同じなら
委譲先をはめ込めれるのが欲しいです。
単なる関数ポインタの例は、求めて
いません。
C#でdelegate型を引数にとる
ところに、あるインスタンスの
メソッドを渡すと。
どのインスタンスのどのメソッドかまで、
認識して、コールバックできます。
関数ポインタでは、これができない。
STLの関数オブジェクトとか、古い感じの情報にヒントがあるか。調べてみましたが。よくわかりませんでした。
結局、この関数オブジェクトは、僕が求めているモノとは、違うような気がします。
よくわかりませんが。
欲しいのは、どのインスタンスのどのメソッドかまでを特定して、
記憶できる型をどうやって
javaや、C++で実装できるか。
それをインタフェース委譲のように、
委譲先にあらかじめ、仕込んでおくことなしに。
ただ、メソッドのシグニチァが同じであるだけで、どのインスタンスのどのメソッドかまでを特定して記憶できる
C#のデリゲードのような型を。
特殊なコンポーネントを利用せず。
標準的な言語構文のみをつかって、
どのようにしたら、
javaや、C++で、実装できるか?
です。
詳しい方が、いらっしゃいましたら、
教えてください。
A 回答 (4件)
- 最新から表示
- 回答順に表示
No.4
- 回答日時:
> [&obj1](int x, int y){ return obj1.add(x,y);}は、
> 新たに、ラムダ式のようなものを作って、
> delgに指定してるようにみえるです
"ようなもの"じゃなく、これがC++のラムダ式です。
> obj1のaddを直で、取得し、その上記の型の変数や引数で
> 受けることは。
> C++の標準的な構文では、不可能なのでしょうか?
直接取得するのは無理。あえてやるなら
#include <iostream>
#include <functional>
using namespace std;
class foo {
int base;
public:
explicit foo(int b) : base(b) {}
int add(int x, int y) const { return base + x + y; }
// ↓ラムダ式を返すメソッド
function<int(int,int)> add_delg() const { return [this](int x, int y) { return add(x,y); }; }
};
int main() {
function<int(int,int)> delg; // delegate int delg(int,int)
foo obj1(1);
foo obj2(2);
delg = obj1.add_delg();
cout << delg(2,3) << endl;
delg = obj2.add_delg();
cout << delg(2,3) << endl;
}
この回答への補足
素晴らしいです。
なんでもできるんですね。
天才的な人だ。
add_delg
みたいなのが、まさに、それ。
C#の場合は、メソッドそのものが、
直でdelegateに指定できて、
メソッドそのものが、もう
デリゲードそのもののように
見えるんですが。
C++では、
ラムダ式の形をとらないと。
『どのインスタンス』か?
という情報をもったものを
取得する手段がないということですか。
[this]という構文が
このインスタンスです、といって、
そのロジックが、
(int x,int y) { return add(x,y);}
ですといってようです。
昔、メンバー関数を、関数ポインタに
指定しようとして、
コンパイラに怒られて、
あぁ、無理なのか。
そういえば、メンバー関数は
どのインスタンスか?
という情報もあるし。
別物なんだろなと、
思ってたです。
メンバー関数に、直でコールバックするのってどうするんだろ。
って、おもったまま、
今回の回答をもらうまで、
ずっと、わからなかったです。
functin<int(int,int)>
中身がどうなってるか
不思議だけど、
勉強になったです。
No.3
- 回答日時:
Javaだと以下のような記述になると思います。
例:C#
MyClass instance = ...
delegate int Foo(int a, int b);
Foo d = new Foo(instance.method);
int result = d(1, 2);
例: Java(Java8以降)
import java.util.function.BiFunction
MyClass instance = ...
BiFunction<Integer, Integer, Integer> d = (a, b) -> instance.method(a, b);
int result = d.apply(1, 2);
なお引数の個数が0~2の場合はjava.util.functionパッケージの定義済みインターフェースを利用できますが、個数が3つ以上のものは個数毎に個別のインターフェースを自前のライブラリーなどに定義することになります。
この回答への補足
ありがとうごさいます。
No.2のC++の回答も、
No.3のjavaの回答も、
ラムダ式的なもので、
このインスタンスのこのメソッドを
呼ぶようなコードを書いて。
それをfunctin的なシグニチァと戻り型だけを定義した型で受けて
コールバックする感じのようですね。
これだと、この受けてる型自体には、
どのインスタンなのかという情報ないですが、ラムダ式の実装で、どのインスタンスのどのメソッドかをかけば。
実際問題、不便ではない。
どうせ、C#でも、そのデリートに
値を指定する部分で、
obj.addというのを書いて。
このインスタンスのこのメソッドを
渡すとかくのだから。。
C#のデリートが特殊で
No.2, 3のほうが実は標準的な感じに
みえたです。
C#のデリートが、すごく便利なので、
おんなじこと、できんだろか。
前々から、思ってたので、勉強になったです。
javaも8は、ラムダ式かけるんですね
これも、知りませんでした。
No.2の最後で回答の補足で、
した欲張った質問は、
ちょっと、ムリそうな感じではと
思われるです。
僕は、ちょっと、勉強が足りないです。
BiFunctinの中身のソースコードが
どうなってるか想像つかない。
ラムダ式ようなものを、C#のデリート以外の方法で受ける手段としての
インタフェースを定義
できるということすらわかってなかったです。
3つ以上の引数バージョンのインタフェースの実装の想像がつかない。
でも、無知な部分が何かが、
浮き彫りになって、
とても、意味があったです。
No.2
- 回答日時:
> aのfooと、bのbarにそれぞれきちんと
> 区別してコールバックできるのでしょうか。
#include <iostream>
#include <functional>
using namespace std;
class foo {
int base;
public:
explicit foo(int b) : base(b) {}
int add(int x, int y) { return base + x + y; }
};
int main() {
function<int(int,int)> delg; // delegate int delg(int,int)
foo obj1(1);
foo obj2(2);
delg = [&obj1](int x, int y) { return obj1.add(x,y); };
cout << delg(2,3) << endl;
delg = [&obj2](int x, int y) { return obj2.add(x,y); };
cout << delg(2,3) << endl;
}
> function<int,int>は、なぜ、
> intを返すのでしょうか?
function<int,int> ではありません、function<int(int,int)> です。
この回答への補足
さっそく、ありがとうごさいます。
こんな質問にまともに、回答できるとは、
おそらく、スゴ腕な人ではないかと
思うです。
基本的なことを確認したいのですが。
&obj1がobjのアドレスでしょうか。
この場合の[ ]の記号は
どういう意味をもっているのでしょうか?
それで、
[&obj1](int x, int y){ return obj1.add(x,y);}
は、
新たに、ラムダ式のようなものを
作って、
delgに指定してるようにみえるです
この方法だと、大枠、求めてるものに
近く見えるです。
確かに、obj1のaddと、obj2のaddを
うまく呼びわけてるです。
すごいです。
欲張ったように質問して
すいませんが。
特定のインスタンスの特定メソッドを
表すオブジェクトの型、
つまり、C#のデリートに
そっくりな型を実装し、
obj1のaddを直で、取得し、
その上記の型の変数や引数で
受けることは。
C++の標準的な構文では、不可能なのでしょうか?
No.1
- 回答日時:
#include <iostream>
#include <functional>
using namespace std;
int main() {
function<int(int,int)> delg; // delegate int delg(int,int)
delg = [](int x, int y) -> int { return x+y; }; // x,y => x+y
//delg = [](int x, int y) -> char* { return (char*)"hello"; }; // error
cout << delg(2,3) << endl;
}
こんなのですか?
# Javaはわからんです
この回答への補足
さっそく、ありがとうごさいます。
普通の関数ポインタのような
使い方のように見えますが。
function<int,int>が
僕には詳しくわからないのですが。
private method(function<int, int> argcallback) {
int ret = argcallback(2,3);
return ret;
}
というものにたいして、
intを2つ引数にとりintを返すfooメソッドを持つ型のインスタンスaと、
intを2つ引数にとりintを返すbarメソッドを持つ型のインスタンスbとがあり、
a, bが異なる型であったとします。
このとき。
method(a.foo);
method(b.bar);
と書いた時、
aのfoo
と、bのbarにそれぞれきちんと
区別してコールバックできるのでしょうか。
僕が求めているのは、そこで、
どのインスタンスのどのメソッドかを記憶できるか?という点
補足で、質問あるですが。
function<int,int>は、なぜ、
intを返すのでしょうか?
delegate int delg(int,int)
が、コメントでかいてありましたので。
もう少し、わかりやすく、
求めている内容を補足すると。
C#のデリートのように、
インスタンスのメソッド(メンバー関数)
を指定できるか。という点。
単なる関数ポインタのように、
どのクラスにも、属さない
グローバルな位置にある関数を
受けれる
とか、クラスに属していても、
特定のインスタンスにひもづいていない、
staticな関数を受けれる
とか、そういうのではなく、
ある特定のインスタンスのメソッド(メンバー関数)を受けれて。
そのインスタンスのそのメソッドへコールバックするようにできないか?
ということです。
インスタンスは、その時の状態をもっているので、それぞれのインスタンスを区別して指定したメソッドへコールバックしたいのです。
そして、その時、できれば。
(可能であればですが。)
#include <functional>
のように、環境によっては、利用できないかもしれないものをできるだけ利用せず、
言語が持ってる標準的な構文だけで、
C#のデリート型のような型を実装する方法が、あれば。
そこを求めています。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 相続・譲渡・売却 土地売却に関することで教えて下さい。 3 2023/03/07 00:10
- Java java 次の機能を有するメソッドを自クラスに作成し、実装したいです。 機能 名前判定機能 →名前が 3 2022/06/16 16:08
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/17 18:41
- 法学 動産の譲渡担保について 1 2023/01/24 23:55
- Java java 飾子を付けること(public static・・・) ・コンソールへの出力処理はmainメ 2 2022/06/16 19:34
- C言語・C++・C# 3つの倍精度浮動小数点値の平均を求めて、3つの引数全てを平均値に変更するメソッドを作成し、キーボード 1 2022/07/13 16:04
- 化学 化学のエンタルピ変化を求め方について ある例題では各物質のモール数を換算して計算することもあり、ある 1 2022/06/20 23:22
- Java javaの質問です 次の機能を有するメソッド4つを自クラスに作成し、実装したいです 【機能】 足し算 1 2022/06/15 17:49
- その他(プログラミング・Web制作) どういうプログラムで組みますか?google colabでやってるんですけど、出来る方お願いします。 1 2022/07/06 09:28
- 化学 化学 クエン酸の解離 2 2022/06/08 17:44
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
#define _CRT_SECURE_NO_WARNIN...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
「指定されたキャストは有効で...
-
足して100になるような乱数のア...
-
(int *)の意味
-
ラップ関数とはどんなものですか?
-
「{ } で囲むだけ」は正しい?
-
C言語 配列と関数の練習問題
-
【C++】関数ポインタの使い方
-
acceptをalarmでタイムアウトさ...
-
C言語で三目並べをするプログラ...
-
【C言語】円の面積を求めるプロ...
-
任意の文字列のアルファベット...
-
C#の質問
-
system関数がうまくいかない
-
c言語
-
if と配列の組み合わせ
-
C++でvectorにテキストファイル...
-
日数チェックプログラム
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
「指定されたキャストは有効で...
-
C言語での引数の省略方法
-
複数桁10進数の*桁目だけを抽出...
-
#define _CRT_SECURE_NO_WARNIN...
-
ラップ関数とはどんなものですか?
-
卒業研究でよく分からないとこ...
-
【C++】関数ポインタの使い方
-
実数の整数部,小数部の取得
-
std::set<int> で、ある値が何...
-
C言語 エラーの原因がわからな...
-
c言語
-
system関数がうまくいかない
-
C++でvectorにテキストファイル...
-
acceptをalarmでタイムアウトさ...
-
if と配列の組み合わせ
-
return 1L
-
「{ } で囲むだけ」は正しい?
-
(マルチスレッド)_beginthrea...
-
PowerShellがうまくいかない
-
このプログラミング誰か教えて...
おすすめ情報