如何设置 Rcpp::List 元素的 class 属性?
How to set the class attribute of an element of an Rcpp::List?
在下面的C++源文件中,在函数glfw_get_monitors
中如何设置对象的每个元素的class属性monitor_ptrs
?
monitor_ptrs[i].attr("class") = "GLFWmonitor";
行抛出一个编译错误:
‘Rcpp::Vector<19>::Proxy’ {aka ‘class Rcpp::internal::generic_proxy<19>’} has no member named ‘attr’
glfw_types.h
#ifndef RCPP_GLFW_TYPES_H
#define RCPP_GLFW_TYPES_H
#include <Rcpp.h>
#include <GLFW/glfw3.h>
void glfw_destroy_monitor(GLFWmonitor*);
//
typedef Rcpp::XPtr<GLFWwindow, Rcpp::PreserveStorage, glfwDestroyWindow> GLFWwindow_ptr;
typedef Rcpp::XPtr<GLFWmonitor, Rcpp::PreserveStorage, glfw_destroy_monitor> GLFWmonitor_ptr;
#endif
C++ 源文件
#include "glfw_types.h"
using namespace Rcpp;
// [[Rcpp::export]]
GLFWmonitor_ptr glfw_get_primary_monitor() {
GLFWmonitor_ptr new_monitor = GLFWmonitor_ptr(glfwGetPrimaryMonitor(), true);
new_monitor.attr("class") = "GLFWmonitor";
return new_monitor;
}
// [[Rcpp::export]]
Rcpp::List glfw_get_monitors() {
int nr_monitors;
GLFWmonitor** monitors = glfwGetMonitors(&nr_monitors);
Rcpp::List monitor_ptrs(nr_monitors);
for(int i = 0; i < nr_monitors; i++) {
monitor_ptrs[i] = GLFWmonitor_ptr((GLFWmonitor*)monitors[i], true);
monitor_ptrs[i].attr("class") = "GLFWmonitor";
}
return monitor_ptrs;
}
这里的问题是 当 您试图分配 class 时。考虑以下更小的示例:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo() {
// Setup the list
Rcpp::List result(1);
// Setup the object that will go in the list
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
// Your approach was to add it to the list, THEN set the class attribute
result[0] = x;
result[0].attr("class") = "bar";
return result;
}
您不能像那样直接将 class 添加到元素访问语法中。但是,您可以 class 一个对象,然后将其添加到列表中:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo() {
// Setup the list
Rcpp::List result(1);
// Setup the object that will go in the list
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
// Your approach was to add it to the list, THEN set the class attribute
// result[0] = x;
// result[0].attr("class") = "bar";
// What we need to do is set the class of that object
x.attr("class") = "bar";
// BEFORE adding it to the list
result[0] = x;
return result;
}
/*** R
foo()
*/
foo()
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
attr(,"class")
[1] "bar"
更新
请注意,在 Rcpp::List
的许多其他情况下,这也是一个问题。考虑以下因素:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List baz() {
Rcpp::List result(1);
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
result[0] = x;
Rcpp::Rcout << result[0][1] << std::endl;
result[0][2] += 1;
return result;
}
将此与使用 Rcpp::IntegerVector
的 std::vector
进行比较:
#include <Rcpp.h>
// [[Rcpp::export]]
void qux() {
std::vector<Rcpp::IntegerVector> result(1);
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
result[0] = x;
Rcpp::Rcout << result[0][0] << std::endl;
result[0][2] += 1;
Rcpp::Rcout << result[0] << std::endl;
}
qux()
1
1 2 4 4 5 6 7 8 9 10
正如在几个地方所讨论的(稍后会尝试回来并添加一些链接),当涉及到 Rcpp::List
时,你通常必须更加明确,因为它的元素可能几乎是 任何东西.
在下面的C++源文件中,在函数glfw_get_monitors
中如何设置对象的每个元素的class属性monitor_ptrs
?
monitor_ptrs[i].attr("class") = "GLFWmonitor";
行抛出一个编译错误:
‘Rcpp::Vector<19>::Proxy’ {aka ‘class Rcpp::internal::generic_proxy<19>’} has no member named ‘attr’
glfw_types.h
#ifndef RCPP_GLFW_TYPES_H
#define RCPP_GLFW_TYPES_H
#include <Rcpp.h>
#include <GLFW/glfw3.h>
void glfw_destroy_monitor(GLFWmonitor*);
//
typedef Rcpp::XPtr<GLFWwindow, Rcpp::PreserveStorage, glfwDestroyWindow> GLFWwindow_ptr;
typedef Rcpp::XPtr<GLFWmonitor, Rcpp::PreserveStorage, glfw_destroy_monitor> GLFWmonitor_ptr;
#endif
C++ 源文件
#include "glfw_types.h"
using namespace Rcpp;
// [[Rcpp::export]]
GLFWmonitor_ptr glfw_get_primary_monitor() {
GLFWmonitor_ptr new_monitor = GLFWmonitor_ptr(glfwGetPrimaryMonitor(), true);
new_monitor.attr("class") = "GLFWmonitor";
return new_monitor;
}
// [[Rcpp::export]]
Rcpp::List glfw_get_monitors() {
int nr_monitors;
GLFWmonitor** monitors = glfwGetMonitors(&nr_monitors);
Rcpp::List monitor_ptrs(nr_monitors);
for(int i = 0; i < nr_monitors; i++) {
monitor_ptrs[i] = GLFWmonitor_ptr((GLFWmonitor*)monitors[i], true);
monitor_ptrs[i].attr("class") = "GLFWmonitor";
}
return monitor_ptrs;
}
这里的问题是 当 您试图分配 class 时。考虑以下更小的示例:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo() {
// Setup the list
Rcpp::List result(1);
// Setup the object that will go in the list
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
// Your approach was to add it to the list, THEN set the class attribute
result[0] = x;
result[0].attr("class") = "bar";
return result;
}
您不能像那样直接将 class 添加到元素访问语法中。但是,您可以 class 一个对象,然后将其添加到列表中:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List foo() {
// Setup the list
Rcpp::List result(1);
// Setup the object that will go in the list
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
// Your approach was to add it to the list, THEN set the class attribute
// result[0] = x;
// result[0].attr("class") = "bar";
// What we need to do is set the class of that object
x.attr("class") = "bar";
// BEFORE adding it to the list
result[0] = x;
return result;
}
/*** R
foo()
*/
foo()
[[1]]
[1] 1 2 3 4 5 6 7 8 9 10
attr(,"class")
[1] "bar"
更新
请注意,在 Rcpp::List
的许多其他情况下,这也是一个问题。考虑以下因素:
#include <Rcpp.h>
// [[Rcpp::export]]
Rcpp::List baz() {
Rcpp::List result(1);
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
result[0] = x;
Rcpp::Rcout << result[0][1] << std::endl;
result[0][2] += 1;
return result;
}
将此与使用 Rcpp::IntegerVector
的 std::vector
进行比较:
#include <Rcpp.h>
// [[Rcpp::export]]
void qux() {
std::vector<Rcpp::IntegerVector> result(1);
Rcpp::IntegerVector x = Rcpp::seq(1, 10);
result[0] = x;
Rcpp::Rcout << result[0][0] << std::endl;
result[0][2] += 1;
Rcpp::Rcout << result[0] << std::endl;
}
qux()
1
1 2 4 4 5 6 7 8 9 10
正如在几个地方所讨论的(稍后会尝试回来并添加一些链接),当涉及到 Rcpp::List
时,你通常必须更加明确,因为它的元素可能几乎是 任何东西.