From 708a0ecd552ad27fa641de50eecba5ac0352b29e Mon Sep 17 00:00:00 2001 From: Jeroen Ooms Date: Tue, 23 Jun 2026 20:19:39 +0200 Subject: [PATCH] Fix ambiguous Vector::operator[] on platforms without LONG_VECTOR_SUPPORT On wasm32 (and other platforms where LONG_VECTOR_SUPPORT is not defined) R_xlen_t is int while ptrdiff_t is long. Subscripting an Rcpp::Vector with a long index then becomes ambiguous between the member operator[] (which needs a long -> int conversion on the index) and the built-in pointer subscript operator[](SEXPREC*, ptrdiff_t) synthesised via the implicit Vector -> SEXP conversion (which needs a user-defined conversion on the object but matches the index exactly). The two implicit conversion sequences are mutually unrankable so overload resolution fails. --- ChangeLog | 5 +++++ inst/include/Rcpp/vector/Vector.h | 15 +++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/ChangeLog b/ChangeLog index 811a2abde..f80d4f939 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +2026-06-23 Jeroen Ooms + + * Add templated integer-index overload on platforms without + LONG_VECTOR_SUPPORT such as wasm32 (PR #1482) + 2026-06-18 Dirk Eddelbuettel * vignettes/rmd/Rcpp.bib: Updated references diff --git a/inst/include/Rcpp/vector/Vector.h b/inst/include/Rcpp/vector/Vector.h index 76bc56020..6599b0e45 100644 --- a/inst/include/Rcpp/vector/Vector.h +++ b/inst/include/Rcpp/vector/Vector.h @@ -21,6 +21,7 @@ #define Rcpp__vector__Vector_h #include +#include namespace Rcpp{ @@ -337,6 +338,20 @@ class Vector : inline Proxy operator[]( R_xlen_t i ){ return cache.ref(i) ; } inline const_Proxy operator[]( R_xlen_t i ) const { return cache.ref(i) ; } +#ifndef LONG_VECTOR_SUPPORT + // On platforms without long vector support (notably wasm32) R_xlen_t is + // int while ptrdiff_t is long, so subscripting with any wider integer + // type would otherwise be ambiguous with the built-in pointer subscript + // synthesised via the implicit Vector -> SEXP conversion. The template + // overloads below provide an exact-match member candidate for every + // integer index type other than R_xlen_t itself. + template + inline typename std::enable_if::value && !std::is_same::value, Proxy>::type + operator[]( T i ){ return cache.ref(static_cast(i)) ; } + template + inline typename std::enable_if::value && !std::is_same::value, const_Proxy>::type + operator[]( T i ) const { return cache.ref(static_cast(i)) ; } +#endif inline Proxy operator()( const size_t& i) { return cache.ref( offset(i) ) ;