2016-02-26 1 views
-1

Attention: Ce problème est limité à MSVSEst-il possible de savoir si le paramètre a été par défaut

J'ai cette signature de la fonction:

void do_somthing(std::vector<foo>& bar={}); 

Est-il possible de différer entre ces deux appels à la fonction:

Première:

do_something() 

Deuxième:

std::vector<foo> v; 
do_something(v); 

En d'autres termes, je veux quelque chose comme:

void do_somthing(std::vector<foo>& bar={}){ 
    if(/* bar was defaulted*/){ 

    } 
    else{ 

    } 
} 

EDIT: Le code actuel:

template<class Tinput_iterator> 
      Tmodel perform_fitting(Tinput_iterator begin_data, Tinput_iterator end_data, std::vector<Tpoint>& inliers = {}); 
+11

Que diriez-vous de * deux * fonctions, une avec (paramètre normal, sans défaut), une sans? – deviantfan

+3

Pourquoi est-ce important? –

+0

@deviantfan sûr que c'est une bonne solution et c'est en fait ce que je prévois de faire. Mais j'étais curieux de savoir si il est possible de le faire dans la même fonction –

Répondre

2

J'ai cette signature de la fonction:

void do_somthing(std::vector<foo>& bar=std::vector<foo>{}); 

Ce ne peut pas compiler, sauf avec les paramètres dangereux du compilateur non standard, vous devez rester loin de.

Dans Visual C particulier ++ permet cela si /Za n'est pas spécifiée, mais avec /W4 produit encore un avertissement comme celui-ci:

stackoverflow.cpp(6): warning C4239: nonstandard extension used: 'default argument': conversion from 'std::vector<foo,std::allocator<_Ty>>' to 'std::vector<foo, 
std::allocator<_Ty>> &' 
     with 
     [ 
      _Ty=foo 
     ] 
stackoverflow.cpp(6): note: A non-const reference may only be bound to an lvalue 
void do_somthing(std::vector<foo>& bar=std::vector<foo>{}){ 
    if(/* bar was defaulted*/){ 

    } 
    else{ 

    } 
} 

Même si nous supposons que vous avez réellement inclus le manquant const pour compiler le code, la réponse serait: non, il est pas possible pour savoir si bar était par défaut. Quoi que vous envisagiez de faire ici, vous devez trouver une solution complètement différente.

+0

Bonne prise, je n'ai pas réalisé que le paramètre n'était pas ''const'. – 5gon12eder

4

Non, pas directement. Le paramètre par défaut est remplacé par le compilateur sur le site d'appel sans aucune autre information. Cependant, il existe une solution simple pour réaliser ce que vous voulez faire: Utiliser la surcharge au lieu des paramètres par défaut.

namespace detail 
{ 
    void 
    do_something_impl(const std::vector<foo>& foos) 
    { 
    // Do things that always need to be done… 
    } 
} 

void 
do_something() 
{ 
    // Do things specific to the no-argument case… 
    detail::do_something_impl({}); 
} 

void 
do_something(const std::vector<foo>& foos) 
{ 
    // Do things specific to the one-argument case… 
    detail::do_something_impl(foos); 
} 

Si votre logique vous oblige à la branche plus souvent - pas seulement au début ou à la fin de la fonction - vous pouvez passer un paramètre booléen supplémentaire pour detail::do_something_impl qui code qui surcharge, il a été appelé à partir.

En général, je recommande d'utiliser avec parcimonie les paramètres par défaut et de préférer la surcharge de fonctions car cela vous donne un meilleur contrôle et souvent aussi de meilleures interfaces (moins surprenantes).

2

Est-il possible de différer entre ces deux appels pour la fonction?

Non, vous pouvez vérifier si le vecteur est vide, mais sinon il n'y a aucun moyen de les distinguer.

Vous pouvez faire des choses intelligentes, comme passer une classe d'utilité qui convertit, mais ce n'est pas à toute épreuve et est la plupart du temps inutile puisque vous pouvez plus facilement faire deux surcharges de fonctions différentes.