2013-02-24 16 views
6

Javaの関数ポインタにパラメータパラメータをバインドする方法はありますか?C++でstd :: bindを使うことができますか?このようなJavaの同等のものは何でしょうか?JavaのC++のstd :: bindに相当しますか?

void PrintStringInt(const char * s, int n) 
{ 
    std::cout << s << ", " << n << std::endl; 
} 

void PrintStringString(const char * s, const char * s2) 
{ 
    std::cout << s << ", " << s2 << std::endl; 
} 

int main() 
{ 
    std::vector<std::function<void(const char *)>> funcs; 
    funcs.push_back(std::bind(&PrintStringInt, std::placeholders::_1, 4)); 
    funcs.push_back(std::bind(&PrintStringString, std::placeholders::_1, "bar")); 
    for(auto i = funcs.begin(); i != funcs.end(); ++i){ 
     (*i)("foo"); 
    } 
    return 0; 
} 

答えて

2

これは、私のように近くにありますあなたが行ごとに翻訳することができると思います。bindは1:1を任意のJava構造にマップしません。 Java7から

static void PrintStringInt(String s, int n) 
{ 
    System.out.println(s + ", " + n); 
} 

static void PrintStringString(String s, String s2) 
{ 
    System.out.println(s + ", " + s2); 
} 

interface MyCall { 
    void fn(String value); 
} 

public static void main(String[] argv) 
{ 
    Vector<MyCall> funcs = new Vector<MyCall>(); 
    funcs.add(new MyCall() { 
     @Override public void fn(String value) {PrintStringInt(value, 4); }}); 
    funcs.add(new MyCall() { 
     @Override public void fn(String value) {PrintStringString(value, "bar"); }}); 
    for(MyCall i : funcs){ 
     i.fn("foo"); 
    } 
} 
+0

+1:はい、私より優れています – Aubin

0

匿名クラスは、元の関数に呼び出しを転送する目的のシグネチャの関数で作成できます。

は、あなたがこれらの機能を持っているとしましょう:

public class StringPrinter { 
    public void printStringInt(String s, int n) { 
     System.out.println(s + ", " + n); 
    } 

    public void printStringString(String s, String s2) { 
     System.out.println(s + ", " + s2); 
    } 
} 

次にあなたが効果的にこれらの関数に引数をバインド匿名クラスを作成することができます。

public static void main(String[] args) { 
    public interface Print1String { 
     public void printString(String s); 
    } 

    List<Print1String> funcs = new ArrayList<Print1String); 
    funcs.add(new Print1String() { 
     public void printString(String s) { 
      new StringPrinter().printStringInt(s, 42); 
     }}); 
    funcs.add(new Print1String() { 
     public void printString(String s) { 
      new StringPrinter().printStringString(s, "bar"); 
     }}); 

    for (Print1String func : funcs) { 
     func.print1String("foo"); 
    } 
} 
+0

あまりにも多くの私のための「新しい」、StringPrinterの2つの方法がこの場合 – Aubin

+0

静的であり、それらはあなたがバインドするかもしれないもののほんの一例でした*に*。一般的に、静的にインスタンスメソッドを優先すると、後で継承と注入の可能性がサポートされます。 –

2

私は恐れていないんだけど、このコードは(悪い)C++のテンプレートを模倣するアプローチです:

abstract class Printer<T> { 
    final T value; 
    Printer(T v) { 
     value = v; 
    } 
    public abstract void print(String s); 
} 

class PrintStringInt extends Printer< Integer> { 
    PrintStringInt(int v) { 
     super(v); 
    } 
    @Override public void print(String s) { 
     System.out.printf("%s, %d\n", s, value); 
    } 
} 

class PrintStringString extends Printer<String> { 
    PrintStringString(String v) { 
     super(v); 
    } 
    @Override public void print(String s) { 
     System.out.printf("%s, %s\n", s, value); 
    } 
} 

public class BindTest { 
    public static void main(String[] args) { 
     Printer<?>[] funcs = { 
     new PrintStringInt(4), 
     new PrintStringString("bar") 
     }; 
     for(Printer<?> p : funcs) { 
      p.print("foo"); 
     } 
    } 
} 

出力:

foo, 4 
foo, bar 
1

上、一つは、メソッドハンドルでも同じことを行う詳細については、クラスjava.lang.invoke.MethodHandleのAPIドキュメントを見ることができました。

0

使用MethodHandle、ここでは一例である

public class HW 
{ 
    int sum; 

    public HW(int a, int b) 
    { 
    super(); 
    this.sum = a+b; 
    } 


    public void hello1(double c) 
    { 
    double newnumber = sum+c; 
    System.out.println("hello from hello1, new number= " + newnumber); 
    } 

    public void hello2() 
    {   
    System.out.println("hello from hello2, sum=" + sum); 
    } 
} 

import java.lang.invoke.MethodHandle; 
import java.lang.invoke.MethodHandles; 
import java.lang.invoke.MethodType; 


public class TestMethodHandle 
{ 

/** 
* @param args 
*/ 
    public static void main(String[] args) 
    { 

    HW hw = new HW(10, 15); 
    MethodHandles.Lookup lookup = MethodHandles.lookup(); 
    MethodHandle mh; 
    try 
    { 
     mh = lookup.findVirtual(HW.class, "hello2", 
              MethodType.methodType(void.class)); 
     mh.invoke(hw); 

     mh = lookup.findVirtual(HW.class, "hello1", 
       MethodType.methodType(void.class, double.class)); 
     mh.invoke(hw, 20); 

    } catch (NoSuchMethodException e) 
    { 
     e.printStackTrace(); 
    } catch (IllegalAccessException e) 
    { 
     e.printStackTrace(); 
    } catch (Throwable e) 
    { 
     e.printStackTrace(); 
    } 

} 
関連する問題