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

标签 c++ templates operator-overloading

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

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

如果我这样编译,我会得到 error: no match for ‘operator+’ (operand types are ‘A<float>::B’ and ‘int’)

我在某个地方发现 operator+(A<T>::B, int)应该声明,所以如果我添加以下内容:

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

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

如果我不尝试调用 b+5,程序会正确编译。

他们(STL 制造商)是如何编程的 vector<T>::iterator operator+用一个整数?我在任何地方都找不到它(而且它有点难以阅读 STL_vector.h)!

谢谢。

最佳答案

您面临的问题是,当您声明一个函数模板时:

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

typename A<T>::B lhs是一个非推导上下文。编译器无法确定什么 T在那种情况下,所以它不会尝试,所以它找不到你的 operator+ .考虑一个简化的例子,例如:

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);

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


您需要申报 operator+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;
    }
};

关于内部类中的 C++ 模板运算符重载,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35583018/

相关文章:

c++ - Visual Studio 和 Xcode 中的 C++ 运算符重载错误

c++ - 调用一个函数的 child 版本而不是 parent ?

c++ - 关于调用 srand 的说明

c++ - 使用 CRTP 时 clang++ 不接受使用模板模板参数

c++ - 有没有办法使用 C++ 类型特征来检查类型是否是模板及其任何属性?

c++ - 构造函数中模板化类成员的继承

c++ - 找不到 C++ 中的重载 << 运算符

c++ - 仅将包含路径的特定子目录添加到包含

android - 将(sdkbox)facebook sdk集成到cocos2dx v3.9上的游戏中

c# - .NET泛型中重载运算符约束的解决方案