compilateur Microsoft (Visual Studio 2017 15.2) rejette le code suivant:résolution de surcharge entre les membres du modèle dans la base et les classes dérivées
#include <type_traits>
struct B
{
template<int n, std::enable_if_t<n == 0, int> = 0>
void f() { }
};
struct D : B
{
using B::f;
template<int n, std::enable_if_t<n == 1, int> = 0>
void f() { }
};
int main()
{
D d;
d.f<0>();
d.f<1>();
}
L'erreur est:
error C2672: 'D::f': no matching overloaded function found
error C2783: 'void D::f(void)': could not deduce template argument for '__formal'
note: see declaration of 'D::f'
Clang rejette aussi:
error: no matching member function for call to 'f'
d.f<0>();
~~^~~~
note: candidate template ignored: disabled by 'enable_if' [with n = 0]
using enable_if_t = typename enable_if<_Cond, _Tp>::type;
GCC l'accepte parfaitement. Quel compilateur a raison?
Addition:
Avec SFINAE sous la forme
template<int n, typename = std::enable_if_t<n == 0>>
...
template<int n, typename = std::enable_if_t<n == 1>>
GCC produit également une erreur:
error: no matching function for call to ‘D::f<0>()’
d.f<0>();
^
note: candidate: template<int n, class> void D::f()
void f()
^
note: template argument deduction/substitution failed:
Aucun lien: Vous voulez probablement utiliser une fonction virtuelle pour différencier entre la base et la méthode dérivée plutôt que SFINAE . –
@HenriMenke Je ne sais pas quel était le cas d'utilisation original, et vous non plus, mais les fonctions virtuelles réalisent quelque chose de complètement différent de ce qui est montré ici. Ceci tire parti de l'héritage de l'implémentation, pas du polymorphisme, et rend les deux fonctions accessibles aux utilisateurs de D. virtual à propos du polymorphisme, et n'aurait qu'une seule fonction disponible pour les utilisateurs de D. –
@ Jarod42 Balise fixe, merci. – Evgeny