【问题标题】:Error "*** was not declared in this scope"错误“***未在此范围内声明”
【发布时间】:2020-09-22 04:36:45
【问题描述】:

在这篇文章中,我定义了一个名为 soft 的函数。当我使用sourceCpp编译时,报错是

  • ZH 未在此范围内声明
  • alpha0H 未在此范围内声明
  • maxRankH 未在此范围内声明

我尝试了很多方法来解决问题“...未在此范围内声明”。但是,我没有找到正确的方法或错误发生的原因。我猜应该和函数中的if-else语句有关,但不确定。

你有什么好主意来解决这个问题吗?提前谢谢!

顺便说一句,我没写Rcpp::NullableRcpp::LogicalMatrix Ome_ = R_NilValue, Rcpp::NullableRcpp::LogicalMatrix Ome1_ = R_NilValue, Rcpp::NullableRcpp::LogicalMatrix Ome2_ = R_NilValue在前面的参数中,而是 Rcpp::LogicalMatrix Ome, Rcpp::LogicalMatrix Ome1, Rcpp::LogicalMatrix Ome2。但是报了一个错误“default missing for ...arguments...”,所以我改成了Rcpp::NullableRcpp::LogicalMatrix....。 p>

#include <RcppArmadillo.h>


// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
Rcpp::List dcSVD(arma::mat X) {
  arma::mat u, v;
  arma::vec d;
  arma::svd(u, d, v, X, "dc");
  return Rcpp::List::create(Rcpp::Named("u") = u,
                            Rcpp::Named("d") = d,
                            Rcpp::Named("v") = v);
  
}


// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
Rcpp::List soft(arma::mat X, Rcpp::Nullable<Rcpp::NumericMatrix> Z_ = R_NilValue, Rcpp::Nullable<Rcpp::LogicalMatrix> Ome_ = R_NilValue, Rcpp::Nullable<Rcpp::LogicalMatrix> Ome1_ = R_NilValue, Rcpp::Nullable<Rcpp::LogicalMatrix> Ome2_ = R_NilValue, Rcpp::Nullable<Rcpp::NumericVector> alpha0_ = R_NilValue, Rcpp::Nullable<Rcpp::NumericVector> maxRank_ = R_NilValue){
  
  
  if (Ome_.isNotNull() && Ome1_.isNotNull() && Ome2_.isNotNull()){
    
    Rcpp::LogicalMatrix Ome(Ome_);
    arma::umat Omega = Rcpp::as<arma::umat>(Ome);
    
    
    Rcpp::LogicalMatrix Ome1(Ome1_);
    arma::umat Omega1 = Rcpp::as<arma::umat>(Ome1);
    
    Rcpp::LogicalMatrix Ome2(Ome2_);
    arma::umat Omega2 = Rcpp::as<arma::umat>(Ome2);
    
    arma::mat X_0 = X % Omega;
    
    if (!Z_.isNotNull()){
      
      Rcpp::NumericMatrix ZH = Rcpp::wrap(X_0);
      
    }else{
      
      Rcpp::NumericMatrix ZH = Rcpp::as<Rcpp::NumericMatrix>(Z_);
    }
    
    
    if (!alpha0_.isNotNull()){
      
      Rcpp::List my_svd = dcSVD(X_0);
      arma::vec d = my_svd["d"];
      Rcpp::NumericVector alpha0H = d(1);
      
    }else{
      
      Rcpp::NumericVector alpha0H = Rcpp::as<Rcpp::NumericVector>(alpha0_);
    }
    
    if (!maxRank_.isNotNull()){
      
      Rcpp::NumericVector maxRankH = -1;
      
    }else{
      
      Rcpp::NumericVector maxRankH = Rcpp::as<Rcpp::NumericVector>(maxRank_);
    }
    
    
  }else{
    
    Rcpp::StringVector ZH = "NULL";
    Rcpp::StringVector alpha0H = "NULL";
    Rcpp::StringVector maxRankH = "NULL";
    
  }  
  
  return Rcpp::List::create(Rcpp::Named("ZH") = ZH, 
                            Rcpp::Named("alpha0H") = alpha0H, 
                            Rcpp::Named("maxRankH") = maxRankH);
  
}

【问题讨论】:

  • c++ 遵循与 R 不同的范围规则。特别是,ZH 在声明它的 { } 之外不可见,就像在 R 中一样。您可能想要移动您的 NULL声明上一级,然后让单独的 if 语句覆盖 NULL 默认值。
  • @ArtemSokolov 谢谢!这样可行。你能帮忙解释一下我经常遇到的另一个错误“static assertion failed: error: type mismatch or unsupported type”吗? ?再次感谢您!
  • 我认为范围界定也不适用于 R。一般来说,我在任何条件之外声明变量,通常使用合理(且可区分)的默认值,所以如果我的if 语句不覆盖它,它们被定义并具有一些有意义的东西(例如,某种形式的NA 或NULL)。
  • @r2evans 试试rm(y); if(TRUE) {y &lt;- 5}; y。即使y 在if { } 范围内声明和定义,它在该范围外也是可见的。这在 C++ 中是不正确的。
  • 好吧,我在想更多 function 和 local,我没有考虑在我的原始声明中循环 if 和 for。从这个意义上说... R 稍微宽松一点,但它不是全局的。 叹息

标签: r rcpp rcpparmadillo


【解决方案1】:

c++ 的范围规则使得在{ } 中声明的变量在该范围之外不可见。考虑将默认定义上移一级,然后让单独的 if 范围覆盖这些默认值:

Rcpp::List soft(...) {

    // Declare variables outside all {}
    //   to make them visible throughout the whole function
    Rcpp::NumericMatrix ZH = R_NilValue;

    // Overwrite the default values inside individual {}
    if (!Z_.isNotNull()){
      ZH = Rcpp::wrap(X_0);
    }else{
      ZH = Rcpp::as<Rcpp::NumericMatrix>(Z_);
    }

    // etc....
}

【讨论】:

    猜你喜欢
    • 2012-04-20
    • 1970-01-01
    • 1970-01-01
    • 2016-07-10
    • 2015-06-23
    • 2010-10-02
    • 2016-02-18
    相关资源
    最近更新 更多