-1

I am not primarily a Java programmer... I would like to find a corresponding Java syntax for class storing a function pointer (templatized) as a variable. The function pointer points to a function "outside" the class. The original code is in C++11:

#include <memory>

template <typename T>
using p_function = T(*)(T, T, T);

template <typename T>
class A
{
   private:
      int k;
      p_function<T> pf;
   public:
      A() { pf = NULL; k = 0; }
      A(p_function<T> pf_, int k_) { pf = pf_; k = k_; }
      T getF(const T a1, const T a2, const T a3) const { return pf(a1, a2, a3); }
};

template <typename T>
T f1(T x, T y, T z) { return x + y + z; }

template <typename T>
T f2(T x, T y, T z) { return x - y - z; }

int main()
{
    A<double> aa (f1<double>, 1.0);
    double val= aa.getF(1.0, 2.0, 3.0);
}

Thinking about the problem, is it reasonable to use the interface?

 public interface Function <T> {
    T pf(T x, T y, T z);
 }

or, is there any better way? Java is relatively rapidly develops, there might be "straighter" constructions than few years ago. There are several requirements which I am not able to join together. Could I ask for a short code sample in Java? Thank you very much for your help.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
justik
  • 4,145
  • 6
  • 32
  • 53
  • To clarify: you're just looking to convert your C++ code to Java, not to actually store native pointers in Java variables and call the C++ code from Java (e.g. using JNI), right? – Wyzard Aug 16 '16 at 11:33
  • @ Wyzard: Not entirely... The code illustrates a combination of several problems; I am interested in Java constructions analogous to C++. To avoid more questions I joined all in a single post... – justik Aug 16 '16 at 19:54

3 Answers3

2

Use java 8. That uses "functional" interfaces (indeed) where an interface defines just one single function.

To not overuse the existing Function class, introduce your own name.

@FunctionalInterface
public interface TriFunction<T> {
    T apply(T x, T y, T z);
}

Marking it with the FunctionalInterface annotation is a practice that prevents adding a second function and such.

class Foo {
    public static Bar hop(Bar x, Bar y, Bar z) { ... }
}

TriFunction<Bar> pf = Foo::hop;
TriFunction<Integer> pg = (x, y, z) -> x + y + z;
Bar bara = pf.apply(a, b, c);

For primitive types better define own interfaces without generic parameter types. Above pg needs 3 times to unbox the wrapper objects, and one time to box it again to an object.

The package java.util.function contains many functional interfaces, like BinaryOperator and IntBinaryOperator.

Joop Eggen
  • 107,315
  • 7
  • 83
  • 138
1

In Java 8, you can use method references. More information here: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html

Basically, Java 8 gives interfaces with only one method the special property that they can be used (sort of) like function pointers. You can assign a lambda or a method reference to an object of such a type.

For example, somewhat related to your question:

public class HelloWorld {

    public interface Function <T> {
        T op(T x, T y);
    }

    public static class Functions {
        static int add(int x, int y) { return x + y; }
        static int sub(int x, int y) { return x - y; }
    }

    static Function<Integer> f1, f2; // <-- "function pointer"

    public static void main(String []args) {
        f1 = Functions::add; // <-- static method reference
        f2 = Functions::sub; // <-- static method reference

        System.out.println("Test: " + f1.op(1,2) + ", " + f2.op(1,2));
    }

}

This code prints, as you'd expect:

Test: 3, -1

So that part of your question should work. However, the part where you define a generic addition is more problematic, because Java doesn't allow you to overload the operator '+'. So the following will not compile in Java:

T add(T x, T y) {
    return x + y; // compile error -> no '+' defined for T
}

If you need T to be base types, you'll need to define your f1 and f2 for each base type you want to use. See also this question: Can I do arithmetic operations on the Number baseclass?

Community
  • 1
  • 1
Joris
  • 412
  • 3
  • 8
-1

I am not sure if I get your question correctly, but have a look at this stackoverflow post.

There are several answers on how to implement function pointer in java.

EDIT

I am not experienced enough in C++ to provide a code sample.

EDIT 2

According to the post I mentioned above, you could try something like this:

public class WithFunction {

//Empty constructor, can be left out
public WithFunction () {...}

//The function you want to reference
public int myReferencedFunction () {...}
}

Then

public class MethodCaller {
  public static Object call (Object theObject, String methodName) {
    return theObject.getClass().getMethod(methodName).invoke(theObject);
    //catch Exceptions
  }
}

Then you can have it like

public static void main (String [] args) {
  WithFunction obj1 = new WithFunction();
  Object result = MethodCaller.call (obj1, "toString");
  int result = (int) MethodCaller.call (obj1, "myReferencedFunction");
}

Notice:

You need to catch a lot of exceptions. Strong error handling needed..

If you use an interface, you can also implement it multiple times and should have the freedom you need

Community
  • 1
  • 1
Dominik Reinert
  • 1,075
  • 3
  • 12
  • 26
  • @ Do Re: However, the problem is more complicated. The function pointer is stored as a class member, points to a function outside the class and it is also templatized. – justik Aug 16 '16 at 09:25