C'è un modo per confrontare il risultato di decltype
in C++ 11?confronto decltype
In altre parole, perché è questo codice non valido:
template<typename T, typename U>
void func(T& t, U& u) {
if(decltype(t) == decltype(u)) {
// Some optimised version for this case
} else {
// A more general case for differing types
}
}
So che in alcuni casi questo particolare problema può essere risolto dal modello di specializzazione parziale; la mia domanda riguarda il confronto di decltype
s.
Modifica: La domanda è arrivata nel corso del tentativo di fornire le impostazioni predefinite per le funzioni gratuite tramite SFINAE. Forse una domanda migliore sarebbe stato il motivo per cui questo non è valido:
template<bool B>
bool SomeFunction() { ... }
template<typename T, typename U>
bool SomeFunctionWrapper(T& t, U& u) {
SomeFunction<decltype(t) == decltype(u)>();
}
allora ho trovato un'altra soluzione (che non coinvolge i modelli a tutti), ma ad un certo punto ho provato questo:
// If it exists, the free function is defined as
// bool AFreeFunction();
typedef struct { char } undefined;
template<typename T = void>
undefined AFreeFunction();
template<bool B>
bool AFreeFunctionWrapper_() {
return false;
}
template<>
bool AFreeFunctionWrapper_<false>() {
return AFreeFunction();
}
bool AFreeFunctionWrapper() {
return AFreeFunctionWrapper_<decltype(AFreeFunction()) == decltype(undefined)>();
}
Alla fine ho ottenuto una variante di questa strategia che funzionava con GCC 4.6, ma poi ho scoperto che gli argomenti del modello predefinito non sono consentiti per le funzioni dei template in MSVC, anche nel 2012 RC. Quindi la soluzione finale è la seguente:
class AFreeFunction {
public:
operator bool() { return false; }
};
Se la funzione è definita, viene richiamata. Se non lo è, viene invece interpretato come un costruttore per la classe, che viene quindi implicitamente trasmesso a bool
.
Si noti che il modulo di funzione gratuito di cui sopra non può essere risolto con una specializzazione parziale; ha bisogno di essere riformulato come modello di classe per consentirlo. – Tom
No, non è necessario essere un modello di classe, può essere un semplice insieme di modelli di funzioni * overloaded *. –
@ n.m. Buon punto – Tom