Ho implementato una classe con std::map
in C++ e creato un'interfaccia utilizzando SWIG per essere chiamata da Java. Tuttavia non esiste un oggetto iteratore che mi consenta di scorrere le voci nel SWIG con lo spostamento std::map
. Qualcuno sa come creare un iteratore?Nessun iteratore per Java quando si utilizza SWIG con std :: map
risposta
Per poter eseguire l'iterazione su un oggetto in Java è necessario implementare Iterable
. Ciò a sua volta richiede una funzione membro chiamata iterator()
che restituisce un'implementazione adeguata di Iterator
.
Dalla tua domanda non è chiaro se i tipi che stai usando nella mappa e se vuoi essere in grado di scorrere le coppie (come faresti in C++), le chiavi oi valori. Le soluzioni alle tre varianti sono sostanzialmente simili, il mio esempio qui sotto ha scelto i valori.
Per prima cosa, il preambolo per il file di interfaccia SWIG ho usato per testare questo:
%module test
%include "std_string.i"
%include "std_map.i"
Al fine di attuare la mappa iterabile che ho dichiarato, definito e avvolto un'altra classe nel file di interfaccia SWIG . Questa classe, MapIterator
implementa per noi l'interfaccia Iterator
. È una combinazione di Java e C++ avvolto, in cui uno era più facile dell'altro da scrivere. In primo luogo alcuni Java, un typemap che dà l'interfaccia implementa e poi due dei tre metodi richiesti per l'interfaccia Iterable
, fornita a typemap:
%typemap(javainterfaces) MapIterator "java.util.Iterator<String>"
%typemap(javacode) MapIterator %{
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
public String next() throws java.util.NoSuchElementException {
if (!hasNext()) {
throw new java.util.NoSuchElementException();
}
return nextImpl();
}
%}
Poi forniamo C++ parte MapIterator
, che ha un privato implementazione di tutti tranne l'eccezione che lancia parte di next()
e lo stato necessario per l'iteratore (espresso in termini di std::map
proprio const_iterator
).
%javamethodmodifiers MapIterator::nextImpl "private";
%inline %{
struct MapIterator {
typedef std::map<int,std::string> map_t;
MapIterator(const map_t& m) : it(m.begin()), map(m) {}
bool hasNext() const {
return it != map.end();
}
const std::string& nextImpl() {
const std::pair<int,std::string>& ret = *it++;
return ret.second;
}
private:
map_t::const_iterator it;
const map_t& map;
};
%}
Infine abbiamo bisogno di dire che la SWIG std::map
stiamo avvolgendo implementa l'interfaccia Iterable
e fornire una funzione di membro aggiuntivo ai fini del confezionamento std::map
che restituisce una nuova istanza della classe MapIterator
abbiamo appena scritto:
%typemap(javainterfaces) std::map<int,std::string> "Iterable<String>"
%newobject std::map<int,std::string>::iterator() const;
%extend std::map<int,std::string> {
MapIterator *iterator() const {
return new MapIterator(*$self);
}
}
%template(MyMap) std::map<int,std::string>;
Questo potrebbe essere più generico, con le macro per esempio per nascondere i tipi di mappa in modo tale che se si dispone di più mappe è solo una questione di "chiamare" la macro per le mappe appropriate, proprio come si fa con %template
.
C'è anche una piccola complicazione con le mappe di tipi primitivi - è necessario organizzare per il lato Java da utilizzare Double
/Integer
invece di double
/int
(autoboxing credo sia il termine), a meno che non hai deciso di avvolgere coppie già nel qual caso potresti fare una coppia con membri primitivi.
- 1. TypeInitializationException quando si utilizza swig per C#
- 2. C++ std :: map domanda sull'ordine iteratore
- 3. Iterating su std :: map in PHP con SWIG
- 4. Rileva se iteratore è l'ultimo elemento di std :: map
- 5. Nessun avviso quando si utilizza nonnull?
- 6. Stampa dell'indice di un iteratore in std :: map
- 7. Come determinare l'ultimo elemento quando si utilizza un iteratore?
- 8. std :: futuro ancora differita quando si utilizza std :: packaged_task (VS11)
- 9. Nessun test trovato quando si utilizza GTEST con CMake/CTest
- 10. SWIG: come avvolgere std :: string & (std :: string passato per riferimento)
- 11. di riferimento come chiave per std :: map
- 12. std :: map con std :: chiave weak_ptr
- 13. swig nessun modulo denominato _esempio
- 14. map/set iteratore non incrementablemap/set iteratore non incrementabile
- 15. utilizzando BOOST_FOREACH con std :: map
- 16. std :: invalidazione iteratore vettoriale
- 17. Java: iteratore dalla voce TreeMap?
- 18. std :: map ordina per dati?
- 19. Nessun output Log4J in sbt quando si utilizza lo scalatest
- 20. Nessun modulo chiamato 'winrandom' quando si utilizza pycrypto
- 21. strano comportamento quando si utilizza Java operatore ternario
- 22. simbolo indefinito quando si carica estensione PHP realizzato con SWIG
- 23. std :: map thread-safety
- 24. Come passare due parametri quando si utilizza std :: mem_fun?
- 25. Nessun output quando si utilizza `fprintf 'dopo` fwprintf'
- 26. Riferimento ambiguo con tipi generici quando si utilizza JDK 1.8
- 27. Prodotto interno zero quando si utilizza std :: inner_product
- 28. Prevenire restringimento di conversione quando si utilizza std :: initializer_list
- 29. C++ map/set iteratore non dereferibile
- 30. Doxygen riconosce std :: shared_ptr o std :: map
Avrai bisogno di precisare cosa intendi per non "tutte" le voci. Qualcosa di specifico, come l'ultimo elemento mancante? Condivisione di un codice per mostrarci come hai fatto l'interop? –
Siamo spiacenti, per la precisione non sono in grado di eseguire alcuna iterazione. – delita
Una ricerca rapida di Google ha trovato questo: http://chadretz.wordpress.com/2009/11/27/stl-collections-with-java-and-swig/ Forse aiuta – Tim