显式调用 operator<< 的模板化重载会产生错误

Explicitly calling templated overload of operator<< gives error

我有以下代码:

//.hpp
enum class UIDCategory
{
    GoodType //and others
};
typedef unsigned short UID;
typedef UID GoodType;

template<UIDCategory UIDCat> //Yes, UIDCat is supposed to go unused
inline std::ostream& operator<<(std::ostream& str, const UID& uid)
{
    return str << uid;
}

std::ostream& operator<<(std::ostream& str, const Recipe::GoodRatio& goodRatio);

//definition of Rules here

template<>
inline std::ostream& operator<< <UIDCategory::GoodType>(std::ostream& str, const GoodType& goodType)
{
    return str << Rules::goods.at(goodType);
}

//.cpp
std::ostream& operator<<(std::ostream& str, const Recipe::GoodRatio& goodRatio)
{
    return str.template operator<< <UIDCategory::GoodType>(goodRatio.goodType);
}

我正在使用 VC++17。 我在 .cpp 文件中的函数行中收到以下错误:

Rules.cpp(21): error C2677: binary '<': no global operator found which takes type 'UIDCategory' (or there is no acceptable conversion)

我一直在网上搜索解决方案,我发现 template 关键字在对 operator<< <UIDCategory::GoodType>(goodRatio.goodType) 的调用中是必需的,以表示 operator<< 实际上是一个模板,所以我如图所示添加了它,但错误并没有消失。我在这里做错了什么?

这里的整个想法是为 typedef 不引入新类型因此不能用于重载解析的限制提供一个 work-around。当我简单地引入以下重载时,我 运行 陷入了麻烦:std::ostream& operator<<(std::ostream& str, const GoodType& goodType)。 header 等同于 std::ostream& operator<<(std::ostream& str, const unsigned short& goodType),因此 str << aGoodType 是不明确的(它与 std 中的冲突)。

我的代码试图使用户能够通过对 << 运算符进行模板化重载,然后明确地将其专门用于不同的操作,来明确说明要使用 << 运算符的 'overload' 什么UIDCategory.

的成员

对于错误和我正在努力实现的目标,如果能提供任何帮助,我将不胜感激。

在按照 Jonas 的建议制作最小、完整和可验证的示例时,我实际上解决了问题。问题是我使用了错误的 << 运算符调用约定。 我称它为流的成员,而实际上它不是。 所以它应该是 operator<<<UIDCategory::GoodType>(str, goodRatio.goodType) 而不是 str.template operator<< <UIDCategory::GoodType>(goodRatio.goodType).

此外,我认为这对于我试图实现的目标来说是一种令人费解的方法,因此选择了一种具有一些小缺点的更简单的方法。