2017-08-11 2 views
0

Supposons que je veux écrire une fonction qui renvoie le premier élément du conteneur non vide.Comment donner un bon message static_assert aux utilisateurs lorsque le type de retour du template l'empêche d'être instancié?

// REQUIRES: c not empty 
template<typename C> 
auto pointer_to_first(C& c) -> decltype(&(*c.begin())){ 
    return nullptr; // TODO: implement 
} 

Si je tente de l'utiliser avec vector<bool>

vector<bool> vb{false, false, true}; 
pointer_to_first(vb); 

compilateur donne un message d'erreur source de confusion pour les débutants:

error: taking address of temporary [-fpermissive] auto pointer_to_first(C& c) -> decltype(&(*c.begin())){

Il est source de confusion car les débutants ne connaissent pas proxy vector<bool> utilisations et vb n'est pas temporaire.

Je souhaite donc ajouter static_assert s que le conteneur ne peut être vector<bool>, aussi que le conteneur doit avoir begin(), end() ... Je sais comment faire cela, mais le problème est que, puisque la résolution de surcharge ne les utilisateurs ne voient le message d'erreur du compilateur.

Existe-t-il un moyen de contourner ce problème?

Répondre

1

Jusqu'à ce que nous avons concept, vous pouvez ajouter une couche supplémentaire pour permettre d'avoir static_assert et éviter SFINAE:

// Your SFINAE function: 
template<typename C> 
auto pointer_to_first_impl(C& c) -> decltype(&(*c.begin())){ 
    return nullptr;// TODO: implement 
} 

template<typename C> 
decltype(auto) pointer_to_first(C& c) 
{ 
    // You need to implement the traits for the check 
    static_assert(my_cond<C>::value, "type is incorrect"); 
    return pointer_to_first_impl(c); 
}