Is there any way to specialize a function (say, std::swap
) for a private class?
For example, when I test 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 do realize declaring a friend swap
that can be found through ADL avoids this issue for swap
, but that's irrelevant to my question. swap
is just an example.)
You could add a friend
declaration of the std::swap<Inner>(Inner&, Inner&)
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;
}