Function specialization for a private class?

Is there a way to specialize a function (e.g. std::swap ) for a private class?

For example, when I check this:

 #include <algorithm> class Outer { struct Inner { int a; void swap(Inner &other) { using std::swap; swap(this->a, other.a); } }; public: static void test(); }; namespace std { template<> void swap<Outer::Inner>(Outer::Inner &a, Outer::Inner &b) { a.swap(b); } } void Outer::test() { using std::swap; Inner a, b; swap(a, b); } int main() { Outer::test(); return 0; } 

I get this:

 Test.cpp:20:47: error: 'Inner' is a private member of 'Outer' template<> void swap<Outer::Inner>(Outer::Inner &a, Outer::Inner &b) ^ Test.cpp:5:12: note: implicitly declared private here struct Inner ^ Test.cpp:20:64: error: 'Inner' is a private member of 'Outer' template<> void swap<Outer::Inner>(Outer::Inner &a, Outer::Inner &b) ^ Test.cpp:5:12: note: implicitly declared private here struct Inner ^ Test.cpp:20:33: error: 'Inner' is a private member of 'Outer' template<> void swap<Outer::Inner>(Outer::Inner &a, Outer::Inner &b) ^ Test.cpp:5:12: note: implicitly declared private here struct Inner 

(I understand that swap friend declaration, which can be found via ADL, avoids this problem for swap , but that doesn't matter for my question. swap is just an example.)

+4
source share
2 answers

You can add a friend std::swap<Inner>(Inner&, Inner&) declaration inside Outer

 #include <algorithm> class Outer { struct Inner { int a; void swap(Inner &other) { using std::swap; swap(this->a, other.a); } }; friend void std::swap<Inner>(Inner&, Inner&) noexcept; public: static void test(); }; namespace std { template<> void swap<Outer::Inner>(Outer::Inner &a, Outer::Inner &b) noexcept { a.swap(b); } } void Outer::test() { using std::swap; Inner a, b; swap(a, b); } int main() { Outer::test(); return 0; } 

Live example

+4
source

Do not expand the std .

If you want to create a swap function for Inner , make it a private function in Outer

 #include <algorithm> class Outer { struct Inner { int a; void swap(Inner &other) { std::swap(this->a, other.a); } }; static void swap(Inner& a, Inner& b); public: static void test(); }; void Outer::test() { Inner a, b; swap(a, b); } void Outer::swap(Inner& a, Inner& b) { a.swap(b); } int main() { Outer::test(); return 0; } 
+1
source

Source: https://habr.com/ru/post/1498084/


All Articles