2017-02-06 7 views
19

Wie weiß find_type, wo die Funktion typemap ist?
Das Argument, das es empfängt, stammt nicht aus dem Namespace, sondern aus dem Namespace std!Warum funktioniert dieser ADL-Fall?

#include <type_traits> 
#include <memory> 

namespace lib { 
    template<typename T> 
    struct find_type { 
     using type = decltype(typemap(std::declval<T>())); 
    }; 
} 

namespace test { 
    struct Test {}; 
    auto typemap(std::unique_ptr<Test>) -> int;  
} 

static_assert(std::is_same<int, lib::find_type<std::unique_ptr<test::Test>>::type>::value, ""); 

Wie kann dieser Code funktionieren? Was erlaubt die Regel?

Ich testete es mit GCC 6.3 und kling 3.9.1.

+6

Der Parametertyp des Template-Parameters 'T' aus der Struktur' find_type' ist 'std :: unique_ptr '. 'std :: unique_ptr' berücksichtigt den Template-Parameter' test :: Test' für ADL und findet somit die 'typecap'-Funktion im' test'-NS – SebNag

Antwort

19

In der C++ Standard N4618 Abschnitt 3.4.2 [basic.lookup.argdep] (2,2)

Wenn T ein Klassentyp (einschließlich Gewerkschaften) ist, die zugehörigen Klassen sind: die Klasse selbst; die Klasse, von der es ist ein Mitglied, falls vorhanden; und seine direkten und indirekten Basisklassen. Die zugehörigen Namespaces sind die innersten , die Namespaces der zugehörigen Klassen enthalten. Wenn T eine Klassenvorlagenspezialisierung ist, gehören die zugehörigen Namespaces und Klassen außerdem: die Namespaces und Klassen, die den Typen der Vorlagenargumente für Schablonetypparameter zugeordnet sind (mit Ausnahme der Vorlagenvorlage ); die Namespaces, für die Vorlagenvorlagenargumente Mitglieder sind; und die Klassen , von denen alle als Vorlagevorlagenargumente verwendeten Elementvorlagen Mitglieder sind.

Das Argument von typemap ist std::unique_ptr<test::Test>, so Namespace test für Namen nachschlagen betrachtet.

14

Das Argument, das es empfängt, stammt nicht aus dem Namespace, sondern aus dem Namespace std!

Nicht alles!

using type = decltype(typemap(std::declval<T>())); 

Dies ist:

using type = decltype(typemap(std::declval<std::unique_ptr<test::Test>>())); 

Es eine test:: gibt es in, so test der Namensraum zu durchsucht wird.

Verwandte Themen