r-lib / cpp11

cpp11 helps you to interact with R objects using C++ code.
https://cpp11.r-lib.org/
Other
199 stars 46 forks source link

Writable vectors could allow `T&` conversion #335

Closed DavisVaughan closed 1 month ago

DavisVaughan commented 1 year ago
cpp11::cpp_function("
SEXP f() {
  cpp11::writable::integers foo({1, 2, 3});
  std::for_each(foo.begin(), foo.end(), [](int& m) {m;});
  return R_NilValue;
}
")
using C++ compiler: ‘Apple clang version 14.0.3 (clang-1403.0.22.14.1)’
using C++11
using SDK: ‘MacOSX13.3.sdk’
/private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:53: warning: expression result unused [-Wunused-value]
  std::for_each(foo.begin(), foo.end(), [](int& m) {m;});
                                                    ^
In file included from /private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:1:
In file included from /Users/davis/Library/R/arm64/4.3/library/cpp11/include/cpp11.hpp:5:
In file included from /Users/davis/Library/R/arm64/4.3/library/cpp11/include/cpp11/as.hpp:7:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/string:551:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/string_view:222:
In file included from /Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/algorithm:1738:
/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/include/c++/v1/__algorithm/for_each.h:26:5: error: no matching function for call to object of type '(lambda at /private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:41)'
    __f(*__first);
    ^~~
/private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:8: note: in instantiation of function template specialization 'std::for_each<cpp11::writable::r_vector<int>::iterator, (lambda at /private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:41)>' requested here
  std::for_each(foo.begin(), foo.end(), [](int& m) {m;});
       ^
/private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:41: note: candidate function not viable: no known conversion from 'cpp11::writable::r_vector<int>::proxy' to 'int &' for 1st argument
  std::for_each(foo.begin(), foo.end(), [](int& m) {m;});
                                        ^
/private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.cpp:8:41: note: conversion candidate of type 'void (*)(int &)'
1 warning and 1 error generated.
make: *** [/private/var/folders/by/4wf2qrmn4_j93s5k5k5fzrx00000gp/T/RtmpD58Szw/code_7cb8d46b5d.o] Error 1
make: *** Waiting for unfinished jobs....
Error: Compilation failed.
no known conversion from 'cpp11::writable::r_vector<int>::proxy' to 'int &' for 1st argument

Looks like both cpp11::integers and cpp11::writable::integers allows for int m and const int& m but the writable version should also allow int& m if we can make it do that

We will need to think about how strings work here.

Could also be tricky with ALTREP, not sure

Probably around here, with the T conversion: https://github.com/r-lib/cpp11/blob/500f642b4ea132ec8c168fc70a28e81e9510ece3/inst/include/cpp11/r_vector.hpp#L252

DavisVaughan commented 1 year ago

I'm actually not sure we could do this since for ALTREP vectors we wouldn't be able to give out a reference to some existing place in an underlying vector.