Frage

Sehen Sie das folgende Programm:

    namespace NS2 {
      class base { };

      template<typename T>
      int size(T& t) {
        std::cout << "size NS2 called!" << std::endl;
        return sizeof(t);
      } 
    };

    namespace NS1 {
      class X : NS2::base { };
    }

    namespace NS3 {
      template<typename T>
      int size(T& t) {
        std::cout << "size NS3 called!" << std::endl;
        return sizeof(t) + 1;
      }

      template<typename T>
      class tmpl 
      {
      public:
        void operator()() { size(*this); }
      };
    };

int main() +{
  NS3::tmpl<NS1::X> t;
  t();
  return 0;
}

Mein Compiler (gcc 4.3.3) kompiliert nicht das Programm, da der Aufruf an Größe mehrdeutig ist. Der Namensraum NS2 scheint auf den Satz von assoziierten Namensräume für die Größe Anruf in der Klasse tmpl hinzugefügt werden. Auch nach dem Abschnitt über Koenig Lookup in der ISI Standard-Lesen bin ich nicht sicher, ob dieses Verhalten Standard entsprechen ist. Ist es? Hat jemand wissen, einen Weg, um dieses Verhalten zu arbeiten, ohne die Größe Gespräch mit dem NS3 Präfix qualifiziert?

Vielen Dank im Voraus!

War es hilfreich?

Lösung

Template Argumente und Basisklassen sowohl beeinflussen ADL, so denke ich, GCC richtig ist, hier:. NS3 kommt aus dem aktuellen Bereich, NS1 von dem X-Template-Argumente, und NS2 von der Basisklasse der Vorlage Arguments

Sie haben irgendwie eindeutig zu machen; Ich würde vorschlagen, eine oder mehrere der Funktionen umbenennen, wenn möglich, oder vielleicht SFINAE verwenden, um die Funktionen eindeutig machen.

(ähnliche Situation: Beachten Sie, dass boost :: noncopyable ist eigentlich "typedef noncopyable _ :: noncopyable noncopyable," so dass der Boost-Namespace wird nicht auf den ADL Satz von Typen hinzugefügt, die ihnen daraus ableiten.)

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top