Vorrei verificare se un tipo proviene da un determinato spazio dei nomi. Ecco quello che mi si avvicinò con:Verificare se un tipo proviene da un determinato spazio dei nomi
#include <utility>
namespace helper
{
template <typename T, typename = void>
struct is_member_of_sample : std::false_type
{
};
template <typename T>
struct is_member_of_sample<
T,
decltype(adl_is_member_of_sample(std::declval<T>()))> : std::true_type
{
};
}
namespace sample
{
template <typename T>
auto adl_is_member_of_sample(T &&) -> void;
}
// -- Test it
namespace sample
{
struct X;
}
struct Y;
static_assert(helper::is_member_of_sample<sample::X>::value, "");
static_assert(not helper::is_member_of_sample<Y>::value, "");
int main(){}
Questo funziona bene finché non si aggiunge adl_is_member_of_sample
al proprio spazio dei nomi (o anche il namespace globale). E, naturalmente, dovrei creare un tale costrutto per ogni spazio dei nomi che voglio testare.
Esiste un modo migliore per verificare in fase di compilazione se un tipo proviene da un determinato spazio dei nomi?
Razionale o "Perché dovrei volere che":
In un EDSL, sto controllando tratti del tipo in fase di compilazione per vedere se certe espressioni sono validi o meno. Alcuni di questi caratteri sono abbastanza semplici: se una classe ha un using is_numeric = void
, allora lo considero come un'espressione numerica. Funziona bene.
is_numeric
è piuttosto generico. Altri potrebbero usarlo pure. Ho quindi pensato di supportare il tratto con un controllo che il tipo provenga dallo spazio dei nomi previsto.
Questa soluzione è piuttosto invadente. Per inserire questo in una libreria, credo che creerò una macro per definire gli spazi dei nomi, che imposta 'adl_is_member_of_sample()' in posizione dopo 'namespace xxx {'. – Lingxi
A proposito, c'è un nome per la tecnica che hai usato con il modello 'is_member_of_sample'? – Lingxi
@Lingxi SFINAE. –