模板和非模板函数之间的C++重载解析

sta*_*ror 3 c++ templates overload-resolution

我对模板和非模板函数之间的c ++重载解析感到困惑,以下是示例:

class Stream {};

struct M
{
    M(float v) {}
};

template <class T>
Stream& operator<<(Stream& stream, T& v) {}

Stream& operator<<(Stream& stream, const M& v) {}

int main()
{
    Stream stream;
    int a = 1;

    stream << a; // sample 1
    stream << a * a; // sample 2

    return;
}
Run Code Online (Sandbox Code Playgroud)

这里,示例1调用模板函数.示例2提供了一个int&&类型参数,可以隐式地转换const M&为非模板,而不是模板T = const int.

样本2的重载分辨率会发生什么?

Nat*_*ica 5

这与模板没有任何关系.在

stream << a * a;
Run Code Online (Sandbox Code Playgroud)

a * a实现右值.由于你的模板函数占用了T&它不能绑定到临时函数所以它被作为可行的重载被丢弃.

这使您可以使用用户定义的转换为M

Stream& operator<<(Stream& stream, const M& v)
Run Code Online (Sandbox Code Playgroud)

作为唯一可行的超载.


如果您更改模板以使用转发参考,例如

template <class T>
Stream& operator<<(Stream& stream, T&& v) 
Run Code Online (Sandbox Code Playgroud)

那么在两种情况下都会调用它,因为你会获得完全匹配.请注意,您应该限制T使用SFINAE,否则这个过载将与海盗一切相匹配.

另外你可以使用

template <class T>
Stream& operator<<(Stream& stream, const T& v)
Run Code Online (Sandbox Code Playgroud)