ADL und C++11 Alias templates
-
Hallo,
wie kann ich in folgendem Beispiel erreichen, das der operator- durch ADL gefunden wird?
template <typename T> class Foo {}; namespace test { template <class T> using Test = Foo<T>; template <typename T> void operator-(Test<T>, Test<T>) {} } int main() { test::Test<int>() - test::Test<int>(); }
-
Bin nicht ganz sicher:
template <typename T> class Foo {}; namespace test { template <class T> using Test = Foo<T>; template <typename T> void operator-(Test<T>, Test<T>) {} } int main() { using namespace test; test::Test<int>() - test::Test<int>(); }
-
Das würde gehen, allerdings muss ich dann immer using namespace test; schreiben. Kennt jemand eine andere Möglichkeit?
-
Machs halt am Anfang des Sourcefiles hin. Und sonst machst du daraus eine freie Funktion. Probleme mit einem Nameclash wirst du nicht haben, weil du ja eine entsprechend eindeutige Überladung anbietest.
-
Das Problem ist, dass Test nicht ein anderer Typ ist, sondern er ist der selbe Typ wie Foo.
Deses using ist nur ein Typedef - mehr nicht.
Deshalb die Gretchen Frage: was willst du denn erreichen?
-
pyhax schrieb:
wie kann ich in folgendem Beispiel erreichen, das der operator- durch ADL gefunden wird?
Durch ADL gar nicht.
If T is a class type (including unions), its associated classes are: the class itself; the class of which it is a
member, if any; and its direct and indirect base classes. Its associated namespaces are the namespaces
of which its associated classes are members. Furthermore, if T is a class template specialization,
its associated namespaces and classes also include: the namespaces and classes associated with the
types of the template arguments provided for template type parameters (excluding template template
parameters); the namespaces of which any template template arguments are members; and the classes
of which any member templates used as template template arguments are members. [ Note: Non-type
template arguments do not contribute to the set of associated namespaces. — end note ]Die Klasse lebt im globalen Namensraum, unabhängig davon, dass der gewählte Bezeichner, der auf sie verweist, zufällig in test lebt. test ist damit nicht assoziert mit test::Test<T>, es sei denn, T ist selbst mit test assoziert. Alternativ könnte man auch Foo von einer Klasse in test erben lassen.
namespace test { struct dummy {}; } template <typename T, typename = test::dummy> class Foo {}; namespace test { template <class T> using Test = Foo<T>; template <typename T> void operator-(Test<T>, Test<T>) {} } int main() { test::Test<int>() - test::Test<int>(); }namespace test { struct dummy {}; } template <typename T> class Foo : private dummy {}; namespace test { template <class T> using Test = Foo<T>; template <typename T> void operator-(Test<T>, Test<T>) {} } int main() { test::Test<int>() - test::Test<int>(); }In jedem Fall ist es das Klassentemplate, um das es geht, wie und wo das Aliastemplate deklariert wird, spielt keine Rolle.
Als Merkregel: eine Klasse (oder ein Template) lebt in dem Namensraum, in dem sie definiert wird. Damit kriegt man auch den Fall namenloser Klassen in den Griff.