[Rcpp-devel] Assignment and extraction from a Vector in a templated function

Douglas Bates bates at stat.wisc.edu
Wed Jun 30 17:59:38 CEST 2010


Apparently I have gotten too fancy in writing a templated function to
apply a permutation to Rcpp::Vector classes.  The templates are at the
end of lme4a/src/MatrixNs.h which can be obtained from R-forge under
the lme4 project.  One of them is

    class Permutation {
	Rcpp::IntegerVector d_perm;
	int n;
    public:
	Permutation(Rcpp::IntegerVector&);

	template<int Rtype>
	Rcpp::Vector<Rtype> forward(const Rcpp::Vector<Rtype>&) const;
	template<int Rtype>
	Rcpp::Vector<Rtype> inverse(const Rcpp::Vector<Rtype>&) const;
	template<int Rtype>
	void inPlaceFwd(Rcpp::Vector<Rtype>&) const;
	template<int Rtype>
	void inPlaceInv(Rcpp::Vector<Rtype>&) const;
    };

    template<int Rtype> inline
    Rcpp::Vector<Rtype> Permutation::forward(const
Rcpp::Vector<Rtype>& vv) const {
    	if (vv.size() != n)
	    throw std::runtime_error("size mismatch in permutation");
	Rcpp::Vector<Rtype> ans(n);
	int *ppt = d_perm.begin();
	for (R_len_t i = 0; i < n; ++i) ans[i] = vv[ppt[i]];
	return ans;
    }

This code compiles under 32-bit and 64-bit Linux on R-forge but not
under Windows or Mac OS X.  The compilation transcript under Windows
32-bit contains

g++ -I"R:/R/R-patched/include"   -I"R:/R/lib/CRAN/2.11/Matrix/include"
-I"R:/R/lib/CRAN/2.11/Rcpp/include"      -O2 -Wall  -c Permutation.cpp
-o Permutation.o
In file included from Permutation.cpp:1:0:
MatrixNs.h: In member function 'Rcpp::Vector
MatrixNs::Permutation::forward(const Rcpp::Vector&) const [with int
Rtype = 13]':
Permutation.cpp:32:49:   instantiated from here
MatrixNs.h:274:34: error: invalid use of incomplete type 'struct SEXPREC'
R:/R/R-patched/include/Rinternals.h:333:16: error: forward declaration
of 'struct SEXPREC'
Permutation.cpp:32:49:   instantiated from here
MatrixNs.h:274:34: error: cannot convert 'SEXPREC' to
'Rcpp::traits::storage_type<13>::type' in assignment
MatrixNs.h: In member function 'Rcpp::Vector
MatrixNs::Permutation::inverse(const Rcpp::Vector&) const [with int
Rtype = 13]':
Permutation.cpp:33:27:   instantiated from here
MatrixNs.h:284:34: error: invalid use of incomplete type 'struct SEXPREC'
R:/R/R-patched/include/Rinternals.h:333:16: error: forward declaration
of 'struct SEXPREC'
MatrixNs.h:284:34: error: cannot convert 'SEXPREC' to
'Rcpp::traits::storage_type<13>::type' in assignment
make: *** [Permutation.o] Error 1
  ... done

The function with the instantiation of forward is


RCPP_FUNCTION_2(List, lme4_PermChk, IntegerVector perm, IntegerVector x) {
    IntegerVector zerob = clone(perm); // modifiable copy
    int bb = *(std::min_element(zerob.begin(), zerob.end()));
    if (bb != 0)
	std::transform(zerob.begin(), zerob.end(), zerob.begin(),
bind2nd(minus<int>(), bb));
    MatrixNs::Permutation pp(zerob);
    return List::create(_["forw"] = pp.forward(x),
			_["inv"] = pp.inverse(x));
}

I am not using this code at present and I think I will just remove it
to see if I can get the rest of the package to compile under those
unenlightened operating systems.  Still, I would be grateful if
someone could point out a cleaner way of writing such code.  All I am
doing is copying the elements of one Rcpp::Vector to another by
reordering them according to the 0-based permutation in d_perm.


More information about the Rcpp-devel mailing list