Questo codice non riesce a compilare nella maggior parte dei compilatori, ma in un primo momento ho intuitivamente dovrebbe SFINAE per proteggere me:SFINAE, deduzione vs. instanziazione
typedef void (*A)();
template < typename T >
struct a_metafun { typedef typename T::type type; };
template < typename T >
typename a_metafun<T>::type f(T) {}
template < typename T>
void f(T(*)()) {}
int main() { f(A()); }
posso risolvere il problema in almeno due modi:
1) Modificare la definizione di "metafun" f() per:
template < typename T > typename T::type f(T) {}
2) definiscono "a_metafun" tale che analizza T e ha un tipo, se T ha uno e non fa i f non lo fa ... ma un'istanza senza errori in entrambi i casi:
BOOST_MPL_HAS_XXX_TRAIT_DEF(type)
typedef < template T, bool = has_type<T>::value >
struct a_metafun { };
typedef < template T >
struct a_metafun<T, true> { typedef typename T::type type };
Upon guardando 14.8.2 (C++ 03) sembra a me come specifica esattamente in quali condizioni può applicare SFINAE. C'è un posto migliore per guardare? Il fallimento nell'istanziazione di un modello già dedotto, anche durante la deduzione di un altro, non sembra essere incluso in questo elenco.
Un'altra direzione che ho preso per interpretare ciò che rende questo illegale è che la detrazione di a_metafun è già avvenuta e l'istanziazione dei suoi interni è ciò che sta causando l'errore. SFINAE non si applica durante l'istanziazione ma solo durante la deduzione o mi sbaglio? Nel secondo caso però, a_metafun è stato correttamente e istanziato con una buona struttura, ma semplicemente non ha una definizione di "tipo" all'interno, il che significa che il modello che tenta di creare un'istanza non riesce a causa della sostituzione.
Fondamentalmente mi sto chiedendo cosa nello standard specifica il comportamento a cui sto assistendo. Ogni compilatore che ho provato si lamenta, anche con il comeau. Sono dell'opinione che abbiano ragione nel farlo, non sono completamente sicuro del perché.
Quindi, esperti ... che cosa è? Perché l'istanziazione del tipo, anche nel contesto della deduzione in f() causa un errore piuttosto che l'esclusione di SFINAE?
Penso che dovrebbe fallire in C++ 11, non in C++ 03 però. La regola SFINAE (o meglio le * wordings *) è leggermente cambiata in C++ 11. – Nawaz