调用专门的ostream操作

问题描述:

我有以下代码...调用专门的ostream操作

#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操作符的专门化而苦恼。

+0

可能重复的是它不可能手动调用C++操作符?](http://stackoverflow.com/questions/7225962/is-it-not-possible-to-call-c-operators-manually) – Pradhan 2015-03-30 21:22:44

+1

虽然可怕,但运营商(std :: cout,42) WhozCraig 2015-03-30 21:24:09

+1

@Pradhan不是真的很愚蠢,对吧?正如你所关联的问题主要是关于为基本类型重载'operator +'。 – vsoftco 2015-03-30 21:30:46

快速回答:

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

我觉得你有实现自己的模板类用操纵朋友ostream& operator<<(ostream&)好得多,并保持状态作为成员变量(通过构造函数初始化)。见here(除了模板的一部分)

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; 
你的代码将被视为有效的[
+0

不错,我在这里看到的唯一问题是'throw'永远不会执行。如果你通过其他任何东西而不是标签,那么'std''运算符 vsoftco 2015-03-30 21:42:35

+0

@vsoftco你可以把它看作是一个守卫如果有人向enum添加更多标签并忘记更新'operator Brian 2015-03-30 21:51:18

+0

的确,好点! – vsoftco 2015-03-30 21:51:52