2017-10-08 6 views
7

Après un moment, j'ai découvert à nouveau une puissance du modèle paramètres-modèle. Voir par exemple l'extrait suivant:Existe-t-il un moyen de déduire des modèles d'alias au modèle de paramètre de modèle tout en préservant sa propriété de contexte déduit

template <template <class> class TT, class T> 
void foo(TT<T>) { 
} 

template <class T> 
using typer = T; 

int main() { 
    foo<typer>(int{}); 
} 

Le modèle d'alias est passé au modèle en tant que modèle-paramètre modèle et est utilisé en outre pour détecter l'autre paramètre du modèle tel qu'il est déduit contexte. Beauté!

Cependant juste au moment où le modèle d'alias lui-même être déduit il semble que les compilateurs deviennent fous:

template <template <class> class> 
struct tag{}; 

template <template <class> class TT, class T> 
void foo(tag<TT>, TT<T>) { 
} 

template <class T> 
using typer = T; 

int main() { 
    foo(tag<typer>{}, int{}); 
} 

[live demo]

Compilateurs bien sûr sont juste comme TT peuvent être déduites à la fois tag<TT> ainsi comme TT<T> paramètres de foo et le int{} ne correspond pas au modèle de modèle avec le modèle de paramètre de type. Y at-il un moyen de préserver le contexte de déduction pour T mais faire TT contexte non déduit dans TT<T>?

P.S. Mes intentions sont pures et ce n'est qu'une question théorique sans aucun problème.

+0

Honnêtement, je ne vois aucune utilisation ni pour le premier _beautifulne ss_ ni pour la deuxième tentative. Quoi qu'il en soit, la question est intrigante, +1. – skypjack

+0

@skypjack comme je l'ai dit je n'ai même pas pensé à des usages possibles, donc vous pourriez avoir raison il n'y en a pas ... –

Répondre

2

Je pense qu'il serait plus facile/plus clair d'écrire quelque chose comme:

template <template <class> class TT, class T> 
void foo(tag<TT>, T, std::enable_if_t< std::is_same<T,TT<T>>::value >* = 0) 

ou moins contraint

template <template <class> class TT, class T> 
void foo_impl(tag<TT>, TT<T>){} 

template <template <class> class TT, class T> 
void foo(tag<TT> a, T b){ foo_impl<TT>(a, b); } 

comme une note de côté, cela montre que la note (non normative) en la norme affirmant que Un nom de modèle d'alias n'est jamais déduit est quelque peu inexact ...