简体   繁体   English

C ++ - 自动转换为std :: string

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM