使用模板化适配器将错误编译为运算符重载实例的rhs

时间:2012-05-16 20:12:24

标签: c++ templates compiler-errors operator-overloading

我一直在尝试使用模板化适配器来启用重载运算符。我收到编译错误(gcc 4.5.2),这似乎与我相矛盾。我想知道为什么以及如何绕过它。下面是说明问题的简化代码。

// The adapter
template <typename T>
class A {
    T t;
public:
    A(T t_) : t(t_) {}
};

// Utility function to return an adaptor
template <typename T>
A<T> make_A(T t) {
    A<T> a(t);
    return a;
}

// The operator overload on the adapter
template <typename T>
A<T> &operator<<(A<T> &a, int) {
    return a;
}

// Shows use case
int main(int,char**) {
    auto aa = make_A(1);
    aa << 2;        // Compiles

    // Desired use:
    make_A(4) << 5; // Compile Error
}

错误消息:

main_operatorinsert.cpp: In function ‘int main(int, char**)’:
main_operatorinsert.cpp:28:22: error: no match for ‘operator<<’ in ‘make_A [with T = int](4) << 5’
main_operatorinsert.cpp:18:11: note: candidate is: A<T>& operator<<(A<T>&, int) [with T = int]

为什么行“aa&lt;&lt; 2;”编译,行“make_A(4)&lt;&lt; 5;”才不是? make_A返回与aa相同的类型。为什么编译器会出现不匹配的情况?我怎么能绕过这个?

2 个答案:

答案 0 :(得分:3)

make_A会返回 rvalue ,但您的operator<<需要非const 左值作为第一个参数。你需要重新设计一下这个,如果你真的需要支持make_A(4) << 5;你可以使operator<<成为一个成员函数,但要注意从它返回一个左值引用是危险的

答案 1 :(得分:2)

您不能将临时(make_A(4))绑定到非常量左值引用。

您可以尝试将其设为const引用,或者只是避免使用临时引用。在C ++ 11中,您可以使用右值引用。

请参阅:How come a non-const reference cannot bind to a temporary object?