Here is an actual problem I encountered when developing mobile games in C++. When targeting Android devices, the application has to do some calls from the C++ part to the Java part. These calls are done via the Java Native Interface (JNI), which is accessed via an object of type JNIEnv.
Calling a Java method from Java requires the identifier of the class, of type jclass, and the identifier of the method, of type jmethodID. When all of them are known, we can call for example a static method returning an integer as follows:
JNIenv* env = /* … */; jclass the_class = /* … */; jmethodID the_method = /* … */; const jint result = env->CallStaticIntMethod(the_class, the_method, /* arguments */);
I certainly did not want to write this stuff everywhere and was hoping for something more like:
// This variable represents the function to call. static_method<jint> method = /* … */; // Then we call it like a function. const jint result = method(/* arguments */);
Since all method calls need the same parameters (i.e. the JNI environment, the class, and the method), I put them in a base class from which specialization for the returned type would be created4:
class static_method_base { public: static_method_base ( JNIEnv* env, jclass class_id, jmethodID method_id ); protected: JNIEnv* m_env; jclass m_class; jmethodID m_method; };
Then I would inherit from this class to create a function object for each supported return type. Here for a static method returning an integer:
template< typename R > class static_method; template<> class static_method<jint>: public static_method_base { public: // This constructor seems useless, doesn’t it? static_method_base (JNIEnv* env, jclass class_id, jmethodID method_id) : static_method_base(env, class_id, method_id) {} template<typename... Arg> jint operator()(Arg&&... args) const; };
At this point we have something weird: the only reason we have defined a constructor in static_method<jint> is to be pass its argument to the parent class. Wouldn’t it be better if we could just say “reuse the constructor from the parent”?
This is possible thanks to the using keyword from C++11:
template< typename R > class static_method; template<> class static_method<jint>: public static_method_base { public: // This is concise and precise. using static_method_base::static_method_base; template<typename... Arg> jint operator()(Arg&&... args) const; };
When used like this, the using keyword imports the function into the current class. It is also a way to solve the problem of parent functions hidden by overloads in the child class:
struct base { void foo(); }; struct derived: base { // This declaration hides base::foo(). void foo(int); }; void bar() { derived d; // This fails, derived::foo requires an int argument. d.foo(); }
With the using keyword:
struct base
{
void foo();
};
struct derived: base
{
usingbase::foo;
void foo(int);
};
void bar()
{
derived d;
// This is ok, foo is a member function in derived.
d.foo();
}
4This is simplified for the example. Check https://github.com/IsCoolEntertainment/iscool-core/ for the actual code.