Vraag Voer een 'using std :: foo'-richtlijn lokaal in een constructor-initialisatie-lijst in (C ++)


Gegeven een aangepast type, toont het volgende fragment de algemene benadering voor het toestaan ​​dat een functie automatisch een door de gebruiker verschafte overbelasting specificeert die specifiek is voor het type, of een generieke implementatie van een functie uit de standaardbibliotheek, indien niet.

// assume std::foo is a real function template returning an int
namespace a {
  struct b { };    
  int foo(b& ab) { ... }
}

int bar(a::b& ab)
{
  using std::foo;
  return foo(ab);
}

Deze aanpak kiest automatisch a::foo als voorkeur boven std::foo als het bestaat.

Mijn vraag is of het mogelijk is om een ​​soortgelijk gedrag te bereiken als het betreffende gesprek deel uitmaakt van de initialisatorlijst van een constructor?

struct bar2
{
  bar2(a::b& ab);
  int i;
};

bar2::bar2(a::b& ab)
  : i{foo(ab)} // want a::foo if available, else std::foo
{ }

Natuurlijk zetten using std::foo in het constructorlichaam is het te laat. Maar als ik het voorstel voor de constructeursdefinitie die ik introduceer std::foo naar de globale naamruimte die ook niet wenselijk is.

Is er een manier om het beste van beide werelden te hebben in deze situatie?


12
2018-01-29 00:59


oorsprong


antwoorden:


Volgens Kan een gebruikende instructie in een constructeur-initialisatielijst worden weergegeven? het enige werk is om een ​​eigen statische functie te gebruiken zoals:

struct bar2
{
  bar2(a::b& ab);
  int i;
  private:
  static int wrapper(a::b& f)
  {
      using std::foo;
      return foo(f);
  }
};

bar2::bar2(a::b& ab)
  : i{wrapper(ab)} // want a::foo if available, else std::foo
{ }

In dit geval kunt u de voordelen van de initialisatielijst behouden zonder de initialisatie naar de hoofdtekst van de constructor te verplaatsen. Het OP in de bovenstaande vraag stelt dat het geen ADL biedt, maar wel lijkt voor mij te werken. Om te testen, eenvoudig verwijderen:

int bar(foo f)
{
    std::cout << "custom.\n";
    return 0;
}

5
2018-01-29 02:07