C模板运算符在内部类中重载

如何为类模板的内部类重载运算符?我现在已经搜索了几个小时,但我找不到答案.这是一个不起作用的最小示例:

#include <iostream>
using namespace std;

template <class T>
struct A
{
    struct B
    {
        T m_t;
        B(T t) : m_t(t) {}
    };


};

template <class T>
typename A<T>::B operator+(typename A<T>::B lhs, int n)
{
    lhs.m_t += n;
    return lhs;
}

int main(int argc, char **argv) 
{

    A<float> a;
    A<float>::B b(17.2);
    auto c = b + 5;
    cout << c.m_t << endl;
    return 0;
}

如果我像这样编译,我得到错误:’operator’不匹配(操作数类型是’A< float> :: B’和’int’)

我发现应该声明运算符(A< T> :: B,int),所以如果我添加以下内容:

struct B;
friend B operator+(typename A<T>::B lhs, int n);

在struct A {之后,我收到链接器错误.

如果我不尝试调用b 5,程序将正确编译.

他们(STL制造商)如何使用int编程向量< T> :: iterator运算符?我无法在任何地方找到它(而且有点难以阅读stl_vector.h)!

谢谢.

最佳答案 您面临的问题是当您声明一个函数模板时:

template <class T>
typename A<T>::B operator+(typename A<T>::B lhs, int n)

typename A< T> :: B lhs是非推断的上下文.编译器无法确定该上下文中的T是什么,因此它不会尝试,因此无法找到您的运算符.考虑一个简化的例子:

template <class T> void foo(typename T::type );

struct A { using type = int; };
struct B { using type = int; };

foo(0); // what would T be? 
        // how many other possible T's are there that fit?

为了使模板推导在非推导的上下文中成功,必须明确指定模板类型参数.在这种情况下,语法的这种怪异性编译:

auto c = ::operator+<float>(b, 5);

但可能不是您的预期用途!

您需要在struct B中声明运算符:

struct B
{
    T m_t;
    B(T t) : m_t(t) {}

    // member
    B operator+(int n) {
        return B(m_t + n);
    }

    // or non-member, non-template friend
    friend B operator+(B lhs, int n) {
        lhs.m_t += n;
        return lhs;
    }
};
点赞