专门为私人班级服务?

时间:2013-08-20 21:22:27

标签: c++ private friend template-specialization specialization

有没有办法专门化私有类的函数(比如std::swap)?

例如,当我测试时:

#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;
}

我明白了:

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

(我确实意识到通过ADL声明可以找到的朋友swap可以避免swap的这个问题,但这与我的问题无关。swap只是一个例子。)< / p>

2 个答案:

答案 0 :(得分:4)

您可以在friend

内添加std::swap<Inner>(Inner&, Inner&) 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

答案 1 :(得分:1)

不要扩展std命名空间。

如果要为Inner创建交换功能,请在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;
}