[英]C++ - auto casting to std::string
I have this code 我有这个代码
template <typename T>
class KeyValueProperty {
protected:
T value = T();
std::string key = "";
public:
KeyValueProperty(const std::string & key) : key(key) { }
T & operator = (const T &i) { return value = i; };
operator const T & (){ return value; };
};
struct T2 {
KeyValueProperty<std::string> x {"x"};
KeyValueProperty<double> y {"y"};
};
and in main 在主要的
T2 tx;
tx.x = "hellow";
tx.y = 10;
std::cout << static_cast<std::string>(tx.x) << ::std::endl;
std::cout << tx.y << ::std::endl;
This is working correctly. 这是正常的。 However, doing only this
但是,只做这个
std::cout << tx.x << ::std::endl;
will end up in 将最终进入
error C2679: binary '<<': no operator found which takes a right-hand operand of type 'Test::KeyValueProperty' (or there is no acceptable conversion)
错误C2679:二进制'<<':找不到哪个运算符采用'Test :: KeyValueProperty'类型的右手操作数(或者没有可接受的转换)
Is it possible to have auto-conversion, or I must manually call casting? 是否可以进行自动转换,或者我必须手动调用强制转换?
The reason ty
works even without a custom operator<<
is because there already exists an operator<<(std::ostream&, double)
, and the compiler can also see that it can make a double
out of your class. 即使没有自定义
operator<<
ty
工作的原因是因为已经存在operator<<(std::ostream&, double)
,编译器也可以看到它可以使你的类成为double
的。 It does so and we're happy. 它这样做,我们很高兴。
However, there is no operator<<(std::ostream&, std::string)
. 但是,没有
operator<<(std::ostream&, std::string)
。 If there was, the same logic would apply and we'd still be happy. 如果有的话,同样的逻辑适用,我们仍然会感到高兴。 Instead, there is:
相反,有:
template <class CharT, class Traits, class Allocator>
std::basic_ostream<CharT, Traits>&
operator<<(std::basic_ostream<CharT, Traits>& os,
const std::basic_string<CharT, Traits, Allocator>& str);
That is, a generic insertion operator for any kind of basic_string
. 也就是说,任何类型的
basic_string
的通用插入运算符。
Although there exist some template arguments that would make this as if it were operator<<(std::ostream&, std::string)
, the compiler isn't going to try and guess which possible template arguments would allow it to subsequently match a conversion of your class to the result. 虽然存在一些模板参数可以使它好像是
operator<<(std::ostream&, std::string)
,但编译器不会尝试猜测哪些模板参数允许它随后匹配a将您的班级转换为结果。 There are too many combinations, so this isn't permitted. 组合太多,因此不允许这样做。
This is why you had to explicitly turn your object into a std::string
(aka std::basic_string<char>
) - this removes one layer from the problem and it can do regular old type deduction to make this work. 这就是为什么你必须明确地将你的对象变成一个
std::string
(又名std::basic_string<char>
) - 这会从问题中删除一个层,并且它可以进行常规的旧类型推导以使其工作。
The right solution is to give your wrapper class an insertion operator, to sidestep this issue. 正确的解决方案是为您的包装类提供一个插入操作符,以回避此问题。
You must provide an appropriate overload of operator<<, for example: 您必须提供适当的operator <<重载,例如:
template<class T>
std::ostream& operator<<(std::ostream& os, KeyValueProperty<T> const& kvp)
{
return os << T(kvp);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.