【问题标题】:Invoking specialized ostream operator调用专门的 ostream 运算符
【发布时间】:2015-06-04 01:41:34
【问题描述】:

我有以下代码...

#include <sstream>

enum class eTag
{
    A,
    B,
    C
};

template<eTag I> std::ostream& operator<< (std::ostream& str, int i)
{
    return str;  // do nothing
}

template<> std::ostream& operator<< <eTag::A>(std::ostream& str, int i)
{
    return str << "A:" << i;  // specialize for eTag::A
}

template<> std::ostream& operator<< <eTag::B>(std::ostream& str, int i)
{
    return str << "B:" << i;  // specialize for eTag::B
}

template<> std::ostream& operator<< <eTag::C>(std::ostream& str, int i)
{
    return str << "C:" << i;  // specialize for eTag::C
}

int main()
{
    std::ostringstream s;

    // s << <eTag::A>(42) << std::endl;

    return 0;
}

这样编译。但正如您从 main() 中的注释行中看到的那样,我正在努力解决如何实际调用 ostream 运算符的特化。

【问题讨论】:

  • 虽然可怕,operator &lt;&lt; &lt;eTag::A&gt;(std::cout, 42) &lt;&lt; std::endl;。我更好奇为什么你会想要这样做。 `
  • @Pradhan 并不是真正的骗子,对吧?由于您链接的问题主要是关于为基本类型重载operator+
  • 你的操作符有两个参数。你给了它一个。对我来说似乎很清楚!

标签: c++ templates operators specialization


【解决方案1】:
operator<<<eTag::A>(std::cout, 42) << std::endl;

(如果需要,您可以在operator&lt;&lt; 和模板参数列表之间添加一个空格。没有区别。)

这太恶心了。通常我们不会编写需要显式模板参数的运算符。最好做这样的事情:

inline std::ostream& operator<<(std::ostream& os, eTag x) {
    if (x == eTag::A) {
        return os << "A:";
    } else if (x == eTag::B) {
        return os << "B:";
    } else if (x == eTag::C) {
        return os << "C:";
    } else {
        throw std::range_error("Out of range value for eTag");
    }
}

然后:

std::cout << eTag::A << 42 << std::endl;

A good compiler will be able to inline this,因此您的代码将像您刚刚输入一样高效

std::cout << "A:" << 42 << std::endl;

【讨论】:

  • 很好,我在这里看到的唯一问题是throw 永远不会执行。如果你传递的不是标签,那么std operator&lt;&lt; 就会启动。我明白了,如果你有一个更大的enum...
  • @vsoftco 您可以将其视为一个守卫,以防有人向枚举添加更多标签并忘记更新operator&lt;&lt;
【解决方案2】:

快速回答:

operator<< <eTag::A>(std::cout,42);

我认为你最好实现自己的模板类操纵器,朋友ostream&amp; operator&lt;&lt;(ostream&amp;),并将状态保持为成员变量(通过构造函数初始化)。见here(模板部分除外)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-03-31
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    相关资源
    最近更新 更多