Excellent,
Thanks Romain.
Re. code posted at https://gist.github.com/romainfrancois/6695921:
In the real code I extend "A_derived" with other functionality, not
just inherit into it, but this typedef trick will be enough to get me
started. Thanks. I will have to brush up on my C++ some more and see if
it is possible to add this functionality within the typedef
syntax/mechanism, such that the resulting type still acts like a true
class.
To others reading, you can also solve the problem by overwriting the
inherited members in the derived class such that they trivially call
the base class implementation. As described briefly in my original
email.
Luke.
-----Original Message-----
Hello,
Due to the way modules are currently implemented, what goes in .field
and .method must be member of the actual class, not inherited. I'm
sure how to express it otherwise.
So instead of using public inheritance as you do in:
class A_derived : public A<B_derived> {};
You can use a typedef. See the code in this gist:
https://gist.github.com/romainfrancois/6695921
Romain
Le 25/09/13 06:30, Luke.Domanski at csiro.au a ?crit :
That set/group of classes implements a generic base class that will
extended from to provide particular functionality.
I now wish to expose via RCPP_MODULE a class A_derived which
from A<B_derived>. I want to expose member variable var1 and
function
fun1 of class A_derived which are both inherited from A<B_derived>.
no overwriting definition of A_derived::var1 or A_derived::fun1
only A<B_derived>::var1 and A<B_derived>::fun1.
However, the following RCPP_MODULE definition produces the
subsequent compiler error.
RCPP_MODULE(testing) {
class_<A_derived>("A_derived")
.field( "var1", &A_derived::var1)
.method("fun1", &A_derived::fun1)
;
}
test2.cpp: In function 'void _rcpp_module_testing_init()':
test2.cpp:33:37: error: no matching function for call to
'Rcpp::class_<A_derived>::field(const char [5], double
test2.cpp:33:37: note: candidate is:
C:/.../R/win-
library/3.0/Rcpp/include/Rcpp/module/Module_Field.h:68:7:
note: template<class T> Rcpp::class_<Class>::self&
Rcpp::class_::field(const char*, T Class::*, const char*) [with T =
Class = A_derived, Rcpp::class_<Class>::self =
Rcpp::class_<A_derived>]
It seems the compiler is converting A_derived::var1 and fun1 into
their true references A<B_derived>::var1 and fun1, but the Rcpp
templates cannot handle the situation where the referenced variable
function is not a "proper" member of the class.
However, the error goes away if overwrite var1 and fun1 in
A_derived, and implement A_derived::fun1() as:
void A_derived::fun1() {
A<B_derived>::fun1();
};
This is not ideal.
Can someone please help me formulate the correct RCPP_MODULE
Is there something that I am doing wrong, or have I once again
triggered a chain of the template meta program that is not
Full code and error reduct follows:
-----test2.cpp-----
#include <RcppCommon.h>
class B {
public:
B (SEXP b);
};
template <class T> class A {
public:
double var1;
void fun1();
};
class B_derived : public B {
public:
B_derived(SEXP b);
};
class A_derived : public A<B_derived> {};
#include <Rcpp.h>
B::B(SEXP b) {};
template <class T> void A<T>::fun1(){
Rcpp::Rcout << "Object of Type: " << typeid(this).name() <<
}
B_derived::B_derived(SEXP b) : B::B(b) {};
using namespace Rcpp;
RCPP_MODULE(testing) {
class_<A_derived>("A_derived")
.field( "var1", &A_derived::var1)
.method("fun1", &A_derived::fun1)
;
}
----end test2.cpp----
> sourceCpp(file="test2.cpp", verbose=TRUE)
...snip...
g++ -m32 -I"C:/PROGRA~1/R/R-30~1.1/include" -DNDEBUG
-I"C:/.../R/win-library/3.0/Rcpp/include"
-I"d:/RCompile/CRANpkg/extralibs64/local/include" -O2 -Wall
-mtune=core2 -c test2.cpp -o test2.o
test2.cpp: In function 'void _rcpp_module_testing_init()':
test2.cpp:33:37: error: no matching function for call to
'Rcpp::class_<A_derived>::field(const char [5], double
test2.cpp:33:37: note: candidate is:
C:/.../R/win-
library/3.0/Rcpp/include/Rcpp/module/Module_Field.h:68:7:
note: template<class T> Rcpp::class_<Class>::self&
Rcpp::class_::field(const char*, T Class::*, const char*) [with T =
Class = A_derived, Rcpp::class_<Class>::self =
Rcpp::class_<A_derived>]
make: *** [test2.o] Error 1
Error in sourceCpp(file = "test2.cpp", verbose = TRUE) :
Error 1 occurred building shared library.
Cheers,
Luke Domanski.
--
Romain Francois
Professional R Enthusiast
+33(0) 6 28 91 30 30