考虑一下这段C++代码:
struct Foo {
float value;
operator float& () {
return this->value;
}
};
int main() {
Foo foo;
foo=1.0f; //Doesn't compile, foo isn't implicitly converted to a float&
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么不编译?是否有一个特定的原因,这不包括在C++标准中?或者确实存在一个等价物,我只是错误使用它?
想象一下,我有这个结构:
struct Foo {
operator int() {
return 11;
}
operator unsigned int() {
return 22;
}
} foo;
Run Code Online (Sandbox Code Playgroud)
当此结构转换为int时,它返回11,但是当转换为unsigned int时,它返回22.
使用普通函数,我可以使用模板和getter函数来选择:
template<typename T>
T get() {
return (T)foo;
}
Run Code Online (Sandbox Code Playgroud)
现在,当调用此函数时,get<int>()它会返回11,但是当它调用它get<unsigned int>()时会返回22.
直到现在,当我尝试使用lambdas时,一切都没问题:
auto lambda=[](auto type) {
return (decltype(type))foo;
};
Run Code Online (Sandbox Code Playgroud)
现在在lambda(0)返回时调用lambda 11,并将其作为lambda(0U)返回值调用22.
这可以正常工作,虽然相当"hacky",但需要使用类型的实例,这对于较大的类型来说并不理想.因此,实现这一点的另一种方式,甚至是"hackier":
auto lambda=[](auto* typePointer) {
return (decltype(*typePointer))foo;
};
Run Code Online (Sandbox Code Playgroud)
现在将其称为lambda((int*)NULL)返回11但将其称为lambda((unsigned int*)NULL)返回22.您可能已经注意到这是相当冗长和"hacky",所以我尝试了一种更简单和传统的方法:
auto lambda=[]<typename T>() {
return …Run Code Online (Sandbox Code Playgroud) 在下面的代码片段中,convert尝试将其输入转换为Box<Error>:
fn convert<T: Into<Box<Error>>>(input: T) -> Box<Error> {
input.into() // Compiles
// From::from(input) // Fails to compile
}
Run Code Online (Sandbox Code Playgroud)
它适用input.into(),但当使用From::from(T)它不再有效时,它需要T实现Error:
error[E0277]: the trait bound `T: std::error::Error` is not satisfied
--> src/main.rs:4:3
|
4 | From::from(input)
| ^^^^^^^^^^ the trait `std::error::Error` is not implemented for `T`
|
= help: consider adding a `where T: std::error::Error` bound
= note: required because of the requirements on the impl of `std::convert::From<T>` for `std::boxed::Box<std::error::Error>` …Run Code Online (Sandbox Code Playgroud)