2017-08-28 1 views
0

Angenommen, ich möchte eine Funktion implementieren, die die eindeutigen Werte z.Std :: Set von RTYPE-Werten in Rcpp

#include <Rcpp.h> 

using Rcpp::Vector; 
using Rcpp::traits::is_na; 
using Rcpp::IntegerVector; 

template <int RTYPE> 
IntegerVector nunique(const Vector<RTYPE>& x) { 
    std::set<typename Rcpp::traits::storage_type<RTYPE>::type> values; 
    for (int i = 0; i < x.length(); ++i) { 
     if (!is_na<RTYPE>(x[i])) 
     values.insert(x[i]); 
    } 
    return IntegerVector::create(values.size()); 
} 

Dies wird jedoch nicht kompilieren und wirft Fehler wie:

error: call of overloaded 'insert(Rcpp::Vector<19>::const_Proxy)' is ambiguous 
     values.insert(x[i]); 

oder

error: no match for 'operator<' (operand types are 'const Rcomplex' and 'const Rcomplex') 
     { return __x < __y; } 

Gibt es eine Möglichkeit, eine std::set von RTYPE Objekte zu erstellen? Alternativ, wie könnte ich eine Art von Hashes solcher Objekte verwenden, um die eindeutigen Werte zu zählen?

+2

was meinst du mit schreiben? Ist RTYPE ein Typ- oder Integer-Vorlagenparameter? Was ist eine Vektorvorlage? –

+1

naja ... mit dem fehler ist das problem ziemlich klar, oder? Es gibt keine natürliche Reihenfolge von Punkten in einer 2D - Ebene, besonders gibt es keine natürliche Möglichkeit, 'operator <' für komplexe Zahlen zu definieren. Daher müssen Sie, wenn Sie sie in eine Menge einfügen wollen, eine solche Reihenfolge definieren und übergeben Parameter zum Set) – user463035818

+0

@ tobi303 Wenn Sie den Operator definieren, wird eine ganze Reihe von Fehlern des ersten Typs ausgegeben. Vielleicht könnten Sie eine Antwort mit funktionierendem Code schreiben? – Tim

Antwort

0

Wir haben ein paar Beispiele an der Rcpp Gallery, die zeigen, wie dynamische Laufzeitumschaltung basierend auf dem Laufzeit-Laden der SEXP-Typ hier als Kompilierzeit RTYPE kommt.

Der Compiler kann nicht wissen, ob Sie mit einer Ganzzahl oder numerisch aufrufen ... das R-basierte Backend, in das Sie einfügen möchten, benötigt einen Typ. Ich denke, dass Sie tun können, was Sie mit einem std::variant (C++ 17) oder seinem Boost version wollen.

Oder einfach atomare Typen umschalten.