Newsgroup: it.comp.lang.c++
Titolo: non template

Salve,
se possibile, come posso fare una cosa del genere:
#include<limits>
struct A { // deve rimanere non template
    ...
}
int main() {
    A a( std::numeric_limits<int> /* () */ );
    a.get_numeric_limits().is_integer;
}
Grazie.


Quello che scrivi non sembra avere molto senso. Prova a spiegare cosa
cerchi di fare e a quale scopo.
Ciao,
Nicola

 cerchi di fare e a quale scopo.
Mi servirebbe tenere un reference/pointer ad un std::numeric_limits<T>
in una classe che non puo` essere un template. Solo all'atto della
costruzione dell'oggetto specifico quale specializzazione di template
di numeric_limits serve. Inoltre, devo poi poter riottenere quella
specializzazione dall'oggetto.
A a( std::numeric_limits<int>) // con o senza invocare il costrutture
con ()
a.get_numeri_limits().is_ingeter; // qui riottengo
std::numeric_limits<int> e vedo se e` un intero
"A" deve essere una classe senza template, ma niente vieta di fare
funzioni membro template o strutture template annidate.
Lo scopo e` infilare un riferimento ad un std::numeric_limits<T> in
pod_info (segue codice).
L'unico modo che ho trovato e` copiarmi i dati membro della
numeric_limits che servono man mano.
// head
#include<typeinfo>
#include<utility>
#include<boost/any.hpp>
#include<ostream>
namespace pod {
    using std::type_info;
    using std::bad_typeid;
    using std::ostream;
    using boost::any;
    // for friend decl in pod_info
    class pod_info;
    typedef const type_info* const key_t;
    typedef pod_info value_t;
    struct pod_pair; //
    class pod_info {
    public:
	typedef ostream& (*printer_t)(ostream&, const any&);
	const char *name() const { return _name; }
	printer_t printer() const { return _printer; }
	friend struct std::pair<key_t, value_t>;
	friend struct pod_pair;
    private:
	pod_info(const char* name, printer_t printer)
	    : _name(name), _printer(printer) {}
	pod_info(pod_info const& p) {
	    _name = p._name;
	    _printer = p._printer;
	}
	const char* _name;
	printer_t _printer;
    };
    struct bad_podid : public bad_typeid {};
    pod_info const& podid( type_info const& ) throw (bad_podid);
    template<typename T>
	pod_info const& podid( T const& ) throw (bad_podid, bad_typeid)
	{ return podid( typeid(T) ); }
    ostream& operator<<(ostream&, any const&) throw (bad_podid);
}
std::ostream& operator<<(std::ostream& o, boost::any const& a) {
    return pod::operator<<(o,a);
}
// body
#include<map>
#include<boost/preprocessor/seq/for_each.hpp>
#include<boost/preprocessor/seq/enum.hpp>
namespace pod {
    using std::type_info;
    using std::ostream;
    using boost::any;
    struct pod_pair : public std::pair<key_t, value_t> {
	pod_pair( key_t k, const char* name, pod_info::printer_t const&
printer) :
	    std::pair<key_t, value_t>(k, value_t(name, printer) ) {}
    };
    template<typename T>
    ostream& print(ostream& o, const any& a) {
	o << boost::any_cast<T>(a);
	return o;
    }
#define TYPES_SEQ (bool)(short)(unsigned short)(int)(unsigned
int)(long)(unsigned long)(long long)(unsigned long
long)(float)(double)(long double)(const char*)
#define PAIR_ctr(r, data, T) (pod_pair( &typeid(T), #T, &print<T> ))
    pod_pair a[] = {
	BOOST_PP_SEQ_ENUM(BOOST_PP_SEQ_FOR_EACH( PAIR_ctr, ~, TYPES_SEQ))
    };
#undef PAIR_ctr
#undef TYPES
    typedef std::map<key_t, value_t> const map_t;
    map_t m( a, a+sizeof(a)/sizeof(a[0]) );
    // podid
    pod_info const& podid( type_info const& info ) throw (bad_podid) {
	map_t::const_iterator v = m.find( &info );
	if (v != m.end())
	    return v->second;
	throw bad_podid();
    }
    // << any
    ostream& operator<<(ostream& o, any const& a) throw (bad_podid) {
	type_info const& type = a.type();
	pod_info const& info = podid( type ); // throws
	return info.printer()(o, a);
    }
}
#include<iostream>
int main() {
    using namespace boost;
    using namespace std;
    cout << "start" << endl;
    any a;
    try {
	a = 1; cout << a << endl;
	a = 9999999999999999LL; cout << a << endl;
	a = (const char*)("aho"); cout << a << endl;
	a = std::string("embeh"); cout << a << endl; // throws
    } catch (pod::bad_podid const&) { cerr << "bad_podid" << endl; }
    catch (std::bad_typeid const&) { cerr << "bad_typeid" << endl; }
    cout << "end" << endl;
}

 specializzazione dall'oggetto.
Mi rispondo da solo (e non è la prima volta). Il fatto di avere
l'indirizzo di una specializzazione di una funzione template mi ha
fatto credere che potessi averne anche per dei tipi, che è sbagliato.
La funzione in questione non dipende dal tipo del template ne dal
valore tornato ne dagli argomenti, quindi per questo posso
deferenziarla da un puntatore e chiamarla.
Saluti,
alef