c ++重载泛型方法,按引用和按值

c++ overload generic method, by-reference and by-value

我有两个相同的通用方法(编辑:实际上是 operators 但方法的问题是相同的),除了一个通过引用使用其形式参数和其他方法按值使用其形式参数。

struct shout_t {
    template<typename T>
    shout_t& operator<<(T &x) { cout << x; return *this; } // by reference
    
    template<typename T>
    shout_t& operator<<(T x) { cout << x; return *this; } // by value
};

“按引用”方法的目的是允许使用“大”对象而无需复制。 “按值”方法针对文字。

由于“按值”方法可以处理这两种情况(对象本身和文字),这会产生错误:

int main() { // Here "large object" ~ string, "literal" ~ int
    shout_t shout;
    shout << 42; // OK
    shout << "FTL"; // ERROR: Overloaded operator '<<' is ambiguous
}

我正在寻找的行为是如果“按引用”方法适用,请先尝试,如果不适用,则应用“按值”方法。

如何解决这个问题?如何获得两个除了“按值”和“按引用”签名外完全相同的方法的预期行为?

这里有两种情况,您可能想要更改作为参数传递的对象,或者您不想更改。在后一种情况下,作为 const 限定参考传递:

struct shout_t {
    template<typename T>
    shout_t& operator<<(const T &item) { cout << item; return *this; }
};

否则,将转发引用与 std::forward:

结合使用
struct shout_t {
    template<typename T>
    shout_t& operator<<(T&& item) { cout << std::forward<T>(item); return *this; }
};