调用专门的ostream运算符

时间:2015-03-30 21:13:44

标签: c++ templates operators specialization

我有以下代码......

#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运算符的特化。

2 个答案:

答案 0 :(得分:1)

快速回答:

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

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

答案 1 :(得分:1)

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

(如果需要,您可以在operator<<和模板参数列表之间添加一个空格。不会有所作为。)

这非常令人讨厌。通常我们不编写需要显式模板参数的运算符。最好做这样的事情:

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;