Skip to content

Commit 708a0ec

Browse files
committed
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.
1 parent 8d2f8f8 commit 708a0ec

2 files changed

Lines changed: 20 additions & 0 deletions

File tree

ChangeLog

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
2026-06-23 Jeroen Ooms <jeroenooms@gmail.com>
2+
3+
* Add templated integer-index overload on platforms without
4+
LONG_VECTOR_SUPPORT such as wasm32 (PR #1482)
5+
16
2026-06-18 Dirk Eddelbuettel <edd@debian.org>
27

38
* vignettes/rmd/Rcpp.bib: Updated references

inst/include/Rcpp/vector/Vector.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#define Rcpp__vector__Vector_h
2222

2323
#include <Rcpp/vector/Subsetter.h>
24+
#include <type_traits>
2425

2526
namespace Rcpp{
2627

@@ -337,6 +338,20 @@ class Vector :
337338

338339
inline Proxy operator[]( R_xlen_t i ){ return cache.ref(i) ; }
339340
inline const_Proxy operator[]( R_xlen_t i ) const { return cache.ref(i) ; }
341+
#ifndef LONG_VECTOR_SUPPORT
342+
// On platforms without long vector support (notably wasm32) R_xlen_t is
343+
// int while ptrdiff_t is long, so subscripting with any wider integer
344+
// type would otherwise be ambiguous with the built-in pointer subscript
345+
// synthesised via the implicit Vector -> SEXP conversion. The template
346+
// overloads below provide an exact-match member candidate for every
347+
// integer index type other than R_xlen_t itself.
348+
template <typename T>
349+
inline typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, R_xlen_t>::value, Proxy>::type
350+
operator[]( T i ){ return cache.ref(static_cast<R_xlen_t>(i)) ; }
351+
template <typename T>
352+
inline typename std::enable_if<std::is_integral<T>::value && !std::is_same<T, R_xlen_t>::value, const_Proxy>::type
353+
operator[]( T i ) const { return cache.ref(static_cast<R_xlen_t>(i)) ; }
354+
#endif
340355

341356
inline Proxy operator()( const size_t& i) {
342357
return cache.ref( offset(i) ) ;

0 commit comments

Comments
 (0)