[Rcpp-devel] Wrapping std::vector<T> when Rcpp::wrap is user-overloaded for T

Dirk Eddelbuettel edd at debian.org
Wed Oct 14 03:12:26 CEST 2015


On 13 October 2015 at 16:50, Nathanael Fillmore wrote:
| Hi all,
| 
| Thanks for the great library, which I have been using very heavily lately.
| I have been struggling to get Rcpp::wrap(x) to work when x is a
| std::vector of a type with a user-defined wrap function ("non-intrusive
| extension"). Specifically, I wrote a Rcpp::wrap overload for std::pair<T,
| S>, and I want to wrap an std::vector<std::pair<T, S>>, but haven’'t
| been
| able to get this to work.
| 
| Following the instructions at “Extending Rcpp”,
| https://cran.r-project.org/web/packages/Rcpp/vignettes/Rcpp-extending.pdf,
| I wrote the following wrapper for std::pair<T, S>:
| 
| #include <map>
| #include <string>
| #include <utility>
| #include <vector>
| #include <RcppCommon.h>
| 
| // Overloads of "wrap" and "as" need to be in between RcppCommon.h and Rcpp.h
| // or RcppArmadillo.h.
| namespace Rcpp
| {
| template<typename T, typename S>
| SEXP wrap(std::pair<T, S> pair)
| {
|  std::map<std::string, SEXP> ret {
|    std::make_pair(std::string("first"), Rcpp::wrap(pair.first)),
|    std::make_pair(std::string("second"), Rcpp::wrap(pair.second))
|  };
|  return Rcpp::wrap(ret);
| }
| }
| 
| #include <Rcpp.h>
| 
| I then wrote the following test function, which compiles and works as
| expected:
| 
| RcppExport SEXP TestPair()
| {
| std::pair<int, std::string> p = std::make_pair(10, "hi");
| return Rcpp::wrap(p);
| }
| 
| I expected that the following function (which is along the lines of what I
| wanted to use in my real project) would also work:
| 
| RcppExport SEXP TestVectorPair()
| {
| std::vector<std::pair<int, std::string>> p {
|  std::make_pair(10, "hi"),
|  std::make_pair(12, "hello"),
|  std::make_pair(14, "ok")
| };
| return Rcpp::wrap(p);
| }
| 
| However, compilation fails with the error messages pasted at the bottom of
| the mail. My questions are as follows: Am I making an obvious mistake here
| somewhere? Or, if not, is there some way to achieve this? Obviously, a
| simple thing to do would be to write a Rcpp::wrap overloaded for
| std::vector<std::pair<T, S>>, but that seems a bit inelegant.

No, that would be my suggestion. You need to give the compiler something to
match against.  The more specific, the better I'd say.

(I may be overlooking something -- I just glanced at this as I am traveling
right now.)

Dirk




| 
| Many thanks,
| Nate
| 
| Platform info:
| Linux
| gcc (GCC) 5.1.0
| R 3.2.0
| Rcpp 0.12.1
| 
| Error message:
| g++ -I/u/deweylab/sw/R-3.2.0/arch/x86_64-redhat-linux-gnu/lib64/R/include
| -DNDEBUG  -I/usr/local/include   -std=c++11 -g -UNDEBUG -std=c++11
| -I/ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include -fpic
| -g -O2  -c test.cpp -o test.o
| In file included from
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/RcppCommon.h:179:0,
|               from test.cpp:5:
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:
| In instantiation of ‘SEXPREC*
| Rcpp::internal::wrap_dispatch_unknown_iterable(const T&,
| Rcpp::traits::false_type) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’:
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:732:39:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&,
| Rcpp::traits::false_type) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:770:30:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&,
| Rcpp::traits::false_type) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:787:28:
|  required from ‘SEXPREC*
| Rcpp::internal::wrap_dispatch_unknown_importable(const T&,
| Rcpp::traits::false_type) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:807:41:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&,
| Rcpp::traits::wrap_type_unknown_tag) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:
|  required from ‘SEXPREC* Rcpp::wrap(const T&) [with T = std::pair<int,
| std::__cxx11::basic_string<char> >; SEXP = SEXPREC*]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:188:37:
|  [ skipping 8 instantiation contexts, use -ftemplate-backtrace-limit=0 to
| disable ]
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:732:39:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_unknown(const T&,
| Rcpp::traits::false_type) [with T = std::vector<std::pair<int,
| std::__cxx11::basic_string<char> > >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:770:30:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch_eigen(const T&,
| Rcpp::traits::false_type) [with T = std::vector<std::pair<int,
| std::__cxx11::basic_string<char> > >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:787:28:
|  required from ‘SEXPREC*
| Rcpp::internal::wrap_dispatch_unknown_importable(const T&,
| Rcpp::traits::false_type) [with T = std::vector<std::pair<int,
| std::__cxx11::basic_string<char> > >; SEXP = SEXPREC*;
| Rcpp::traits::false_type = Rcpp::traits::integral_constant<bool,
| false>]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:807:41:
|  required from ‘SEXPREC* Rcpp::internal::wrap_dispatch(const T&,
| Rcpp::traits::wrap_type_unknown_tag) [with T = std::vector<std::pair<int,
| std::__cxx11::basic_string<char> > >; SEXP = SEXPREC*]’
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap_end.h:30:38:
|  required from ‘SEXPREC* Rcpp::wrap(const T&) [with T =
| std::vector<std::pair<int, std::__cxx11::basic_string<char> > >; SEXP =
| SEXPREC*]’
| test.cpp:37:22:   required from here
| /ua/nathanae/R/x86_64-unknown-linux-gnu-library/3.2/Rcpp/include/Rcpp/internal/wrap.h:522:2:
| error: static assertion failed: cannot convert type to SEXP
| static_assert( !sizeof(T), "cannot convert type to SEXP" ) ;
| ^
| 
| _______________________________________________
| Rcpp-devel mailing list
| Rcpp-devel at lists.r-forge.r-project.org
| https://lists.r-forge.r-project.org/cgi-bin/mailman/listinfo/rcpp-devel

-- 
http://dirk.eddelbuettel.com | @eddelbuettel | edd at debian.org


More information about the Rcpp-devel mailing list