7
votes

Boost :: Lié avec les pointeurs de fonction NULL

Si le pointeur de fonction incorporé dans un boost :: lind code> objet est null code> / nullptr code> / 0 code> 0 code> , Je dois prendre des mesures autres que l'appelant. Comment puis-je déterminer si l'objet contient un pointeur de fonction NULL?

Addenda H2>
  1. Je ne crois pas que je puisse utiliser et comparer boost :: fonction code> s en tant que boost :: lid code> L'objet de retour est utilisé avec des signatures d'appel variables dans une fonction de modèle . li>
  2. Exemple simplifié: Li> ol>
    Retval do_stuff(boost::function<Retval()> func, enum Fallback fallback)
    {
        if (func.empty())
            return do_fallback(fallback);
        else
            return use_retval(func());
    }
    


4 commentaires

Y a-t-il une raison pour laquelle vous ne pouvez pas utiliser le modèle d'objet NULL et avoir une fonction "null"?


Ouais, l'action prise dépend d'un autre paramètre à la fonction qui se produit, ce n'est pas la même chose pour tous les cas où le boost :: lid contient un nullptr .


Pouvez-vous ajouter un exemple simplifié de votre cas d'utilisation?


Je ne sais pas pourquoi le formatage est bouché pour ce bit de code supplémentaire


4 Réponses :


0
votes

Je suis sûr que l'appelant stimulant :: Lié avec un pointeur NULL (= la la création de l'objet Bind) doit être considéré comme un comportement non défini, même si le crash ne se produit que lors de l'appelant. < / p>


0 commentaires

6
votes

Vous pouvez soit lier à une fonction factice: xxx

... ou, en supposant que vous utilisez boost.bind avec boost. Fonction , renvoyer un objet de fonction construit par défaut et vérifier vide () avant de l'appeler: xxx


concernant la mise à jour:
Je ne vois toujours pas ce que le problème de la liaison à une fonction différente comme ce qui suit serait le suivant: xxx

si vous souhaitez déplacer cette manipulation du code d'appel , vous pouvez imiter la fonction de modèle variadique pour prendre en charge les arités variables: xxx

... ou vous utilisez l'approche ci-dessus pour générer boost :: fonction <> Objets ou vos propres emballages et vérifiez Foncteur.empty () ou similaire dans do_stuff () .


5 commentaires

Je ne fais pas non plus d'entre eux. Je ne peux pas lier à une fonction factice comme "l'action par défaut" que je parle est décidée uniquement une fois que le pointeur de la fonction est jugé null. La signature de fonction varie, l'objet de retour de BOOST :: BIND est transmis à une fonction de modèle.


Je viens de simplifier cela ci-dessus. Mais qu'est-ce qui vous empêche exactement d'utiliser fonctionObject.empty () ...? Peut-être que vous pouvez montrer un exemple simplifié de votre cas d'utilisation?


La mise en œuvre de l'objet retourné est à la manière principalement dans boost / bind / bind_template.hpp - là, vous pouvez voir que la fonction est stockée en privé et qu'aucun accessoires n'est fourni - il est censé être opaque. Je pense que l'approche que vous prenez est imparfaite, vous devez créer vos objets de fonction quelque part - c'est là où vous devriez le réparer.


Cette réponse est bien façonnée. Je devrais essayer vos idées sous peu


Il s'avère donc que, voyant que je faisais la liaison avant le transmettre, la signature d'appel attendue n'a pas changé. C'était simplement un boost :: Fonction , qui permettez-moi d'utiliser la méthode . / Code>. Cette réponse m'a donné les bonnes idées et me met sur la bonne voie.



-1
votes

Vous allez avoir à pirater Boost.

boost :: Lin retour non spécifié-n-n . La seule chose valable avec ces classes est l'opérateur (). La seule autre chose que vous savez est qu'elles sont copieuses constructives et ont un type de type_TYPE (qui, à titre, signifie que vous n'avez pas besoin de modèle pour le type de résultat).

Vous voulez quelque chose d'autre - vous devrez donc trouver la définition de non spécifiée-nn à boost (peut-être plusieurs), hacelez-les à avoir une fonction IS_NULLULL () qui vérifie le Conditions que vous souhaitez, appelez cela comme votre test.

Ceci est, bien sûr, en supposant que vous soyez certain que vous obtiendrez toujours un objet Boost :: Balay'ed dans votre fonction de modèle. Si quelqu'un essaie de passer dans un pointeur de fonction régulier, il ne compilera pas. Travailler autour de cela nécessitera une magie de modèle.


0 commentaires

1
votes

Je créerais un objet wrapper pour le faire. Quelque chose comme le suivant

#include <boost/bind.hpp>
#include <boost/function.hpp>
#include <iostream>

int aFunction(int i, int j)
{
  std::cout<<"In a Function"<<std::endl;
  return i+j;
}

struct DefaultingFromFnPtr : public boost::function< int(int,int) >
{
  explicit DefaultingFromFnPtr( int(*fn)(int,int) ) : fn_(fn) {}
  int operator()(int i, int j) const
  {
    if (fn_!=NULL) return fn_(i, j);
    return 7;
  }
  int(*fn_)(int,int);
};

template<typename T>
void do_stuff( T t )
{
  std::cout<<"RETURNED "<<t()<<std::endl;
}

int main( int argv, const char** argc)
{

  int(*mightBeNullFnPtr)(int,int) = NULL;
  if( argv>1)
  {
    mightBeNullFnPtr = & aFunction;
  }

  int var1 = 10;
  int var2 = 20;

  do_stuff( boost::bind( DefaultingFromFnPtr( mightBeNullFnPtr ), var1, var2 ) );
}


1 commentaires

HM, vous pourriez être sur quelque chose. Je vais essayer.