Vu le code suivantErreur dans le modèle instanciation avant la surcharge
#include <type_traits>
#include <utility>
template <typename T>
class Something {
public:
template <typename F>
auto foo(F&&)
-> decltype(std::declval<F>()(std::declval<T&>())) {}
template <typename F>
auto foo(F&&) const
-> decltype(std::declval<F>()(std::declval<const T&>())) {}
};
int main() {
auto something = Something<int>{};
something.foo([](auto& val) {
++val;
});
}
https://wandbox.org/permlink/j24Pe9qOXV0oHcA8
Lorsque je tente de compiler ce que je reçois l'erreur en disant que je ne suis pas autorisé à modifier une valeur const dans le lambda principale. Cela signifie que d'une manière ou d'une autre les templates sont tous deux instanciés dans la classe et que cela provoque une erreur dure puisque l'erreur est dans le corps du lambda.
Quelles sont les règles à ce sujet? Pourquoi la résolution de surcharge essaie-t-elle d'instancier un modèle qui ne sera jamais appelé? Le const ne devrait jamais être appelé ici alors pourquoi essaie-t-il de l'instancier complètement?
Cependant, chose étrange est que lorsque je change les définitions à retourner par decltype(auto)
et ajouter le code pour faire la même chose que les types de retour à la traîne suggèrent, je ne vois pas une erreur. Indique que les modèles ne sont pas complètement instanciés?
template <typename F>
decltype(auto) foo(F&& f) {
auto t = T{};
f(t);
}
template <typename F>
decltype(auto) foo(F&& f) const {
const auto t = T{};
f(t);
}
Je suppose que le compilateur ne sait pas quelle fonction à appeler avant l'instanciation au moins la signature avec la fonction passée. Mais cela n'explique pas pourquoi la decltype la version (automatique) fonctionne ...
"* l'erreur se produira pendant l'instanciation *" par opposition à quand? La substitution est-elle son propre pas? –
@RyanHaining: lors de l'étape de substitution, le type de retour arrière decltype (...) 'instancie le corps de lambda ... ce qui provoque une erreur. –
Quel est le moyen suggéré pour éviter ce problème ici? Il suffit de passer à 'decltype (auto)'? Je voudrais que la fonction 'foo' soit compatible SFINAE avec le type de retour et aussi que le code utilisateur fonctionne – Curious