C ++:运算符和模板

时间:2012-07-17 20:13:05

标签: c++ class templates operators operator-overloading

以下和我从另一个问题中得到的例子,我理解为什么这不起作用:

struct Foo {
    Foo() {}
    Foo(int) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


struct Bar {
    Bar() {}
    Bar(int) {}
};

Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar b;
    b+1;  // Will work - the int converts to Bar
    1+b;  // Will work, the int converts to a Bar for use in operator+

}

但是,如果我改变它以这种方式使用模板:

template <class T>
struct Foo {
    Foo() {}
    Foo(T) {}
    Foo operator+(Foo const & R) { return Foo(); }
};


template <class T>
struct Bar {
    Bar() {}
    Bar(T) {}
};

template <class T>
Bar operator+(Bar const & L, Bar const & R) {
    return Bar();
}


int main() {
    Foo<int> f;
    f+1;  // Will work - the int converts to Foo
    1+f;  // Won't work - no matching operator
    Bar<int> b;
    b+1;  // DOES NOT WORK
    1+b;  // DOES NOT WORK

}

它不起作用。谁能对此有所了解?模板让我发疯。

感谢。

2 个答案:

答案 0 :(得分:3)

有两个问题。

  1. 您需要将模板类型添加到运算符定义中的参数中。这是必要的,因为它需要使用它们来知道要使用哪个Bar实例化。
  2. 如果您想在模板函数中使用混合运算符(在两种不同类型上运行),则需要为所有混合情况提供定义。否则,模板演绎系统将无法按您的方式工作。
  3. template <class T>
    Bar<T> operator+(Bar<T> const & L, Bar<T> const & R) { // Fixed
        return Bar<T>();
    }
    
    template <class T>
    Bar<T> operator+(Bar<T> const & L, const T & R) { // Added
        return L + Bar<T>(R);
    }
    
    
    template <class T>
    Bar<T> operator+(const T& L, Bar<T> const & R) { // Added
        return Bar<T>(L) + R;
    }
    

答案 1 :(得分:1)

intBar之间没有隐式转换,仅在intBar<int>之间。实际上,您尚未定义类型Bar;相反,对于Bar<T>的各种值,您有一系列T类型。可能你看到编译器错误与operator+的定义有关,尽管它可能隐藏在其他模板类型错误的后面。

我面前没有c ++编译器,但我相信template<class T> Bar<T> operator+(Bar<T> const & L, Bar<T> const & R)会表现得像你期望的那样。