我有一个类似于 boost::any 的类,因为它是一个模板化的容器类。我想要一种将包含的值写入字符串的方法。但是,如果包含的类型不提供流插入运算符,我希望我的方法返回一些默认字符串,而不是编译失败。下面是我已经接近的情况,并且应该清楚地说明我正在尝试做什么:
namespace W {
namespace hide {
template <typename T>
std::ostream& operator<<(std::ostream& out, const T& t) {
return std::operator<<(out, typeid(T).name());
}
}
template <typename T> struct C {
T t_;
std::string ToString() const {
using namespace hide;
std::ostringstream oss;
oss << t_;
return oss.str();
}
};
}
这工作得很好,但有一些警告。例如,如果我想为一个类实际提供一个重载的插入运算符,那么该运算符必须与该类位于同一命名空间中,或者它必须位于 W 命名空间中才能考虑。
对于已经具有非成员 std::operator<< 的任何类型,例如 char 和 std::string,它也存在问题。如果 T 是这些类型之一,则oss << t_
上面的行变得模棱两可。这可以通过在 W 命名空间中为这些类型添加重载来解决,例如:
std::ostream& operator << (std::ostream& out, const std::string& s) {
return std::operator <<(out, s);
}
我的问题是,有没有人找到比这更好的方法?为什么我必须为 std::string 之类的东西添加自己的重载?这都是根据标准支持的,还是我在利用非标准行为?(我正在使用 g++ 4.3.3 进行测试)