如何通过 class 模板专门化运算符函数类型

How can I specialize a operator function type by class template

我有一个像下面这样的 class 并且想通过 class 模板 T 来特化 '->' 运算符。特化应该取决于类型 T 是否是指针类型或不。我已经搜索了解决方案,但没有找到针对此特定问题的任何解决方案。

template <typename T>
class C
{
public:
    // when T is a pointer type
    T operator->()
    {
        return value;
    }

    // when T is not a pointer type
    const T* operator->() const
    {
        return &value;
    }

private:
    T value;
};

void test()
{
    struct Test
    {
        int x, y;
    };

    C<Test> c1;
    C<Test*> c2;

    c1->x = 5; // should both work
    c2->x = 5; // ignoring the fact, that c2's value is undefined
}

感谢您的帮助!

你需要partial specialization 而且您还需要小心取消引用指针。您的原始示例可能会崩溃。

template <typename T>
class C
{
public:
    explicit C(const T& v = T()): value(v) {}
    // when T is not a pointer type
    T* operator->()
    {
        return &value;
    }

private:
    T value;
};

template <typename T>
class C<T*>
{
public:
    explicit C(T* v = nullptr): value(v) {}
    // when T is a pointer type
    T* operator->()
    {
        return value;
    }

private:
    T* value;
};

或者如果你有兼容 C++17 的编译器,你可以使用 if constexpr:

template <typename T>
class C
{
public:
    explicit C(const T& v = T()): value(v) {}
    // when T is not a pointer type
    auto operator->()
    {
        if constexpr (std::is_pointer_v<T>)
            return value;
        else
            return &value;
    }

private:
    T value;
};

测试一下:

int main()
{
    struct Test
    {
        int x, y;
    };

    C<Test> c1({1, 2});
    Test t = {3, 4};
    C<Test*> c2(&t); // Initialize the pointer with some valid address, we are going to dereference it!

    c1->x = 5;
    c2->x = 5;
    std::cout << c1->x << ' ' << c1->y << ' ' << t.x << ' ' << t.y << '\n';
}