专门为一个私人班级设计一个功能

Specializing a function for a private class?

本文关键字:一个 功能      更新时间:2023-10-16

有没有办法为私有类专门化函数(比如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只是一个例子。)

您可以在Outer 中添加std::swap<Inner>(Inner&, Inner&)friend声明

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

实时示例

不要扩展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;
}