初始化grpc::ClientReader遇C2664错误(Windows MSVC环境)求助
环境信息
- 平台:Windows MSVC 2022(v143)
- C版本:C17
- gRPC版本:1.60.0(通过vcpkg安装)
问题代码
std::unique_ptr< grpc::ClientReader<MyData> > reader( stub->StreamService(&context, request) );
错误信息
cannot convert parameter 'std::unique_ptrgrpc::ClientReader<MyData,std::default_deletegrpc::ClientReader
>::unique_ptr(const std::unique_ptrgrpc::ClientReader<MyData,std::default_deletegrpc::ClientReader > &)': 1 from 'std::unique_ptrgrpc::ClientReaderInterface<MyData,std::default_deletegrpc::ClientReaderInterface >' to 'const std::unique_ptrgrpc::ClientReader<MyData,std::default_deletegrpc::ClientReader > &'
解决方案
方案1:使用接口类型声明变量(推荐)
gRPC生成的Stub流式方法默认返回std::unique_ptr<grpc::ClientReaderInterface<T>>,这是所有客户端流式读取器的抽象接口,grpc::ClientReader<T>是它的具体实现。直接用接口类型接收返回值即可,完全不影响后续调用流式读取的所有方法:
std::unique_ptr<grpc::ClientReaderInterface<MyData>> reader( stub->StreamService(&context, request) );
方案2:显式转换为具体类型(仅特殊场景使用)
如果必须依赖ClientReader<T>的非接口方法(不推荐,违背面向接口的设计原则),可以通过release()和static_cast完成类型转换,但需确认Stub返回的对象实际就是ClientReader<T>实例(gRPC默认实现符合此条件,但版本迭代可能存在变更风险):
auto temp_reader = stub->StreamService(&context, request); std::unique_ptr<grpc::ClientReader<MyData>> reader( static_cast<grpc::ClientReader<MyData>*>(temp_reader.release()) );
原因说明
std::unique_ptr不支持隐式的上下类型转换——即使ClientReader<T>继承自ClientReaderInterface<T>,std::unique_ptr<ClientReaderInterface<T>>也无法直接赋值给std::unique_ptr<ClientReader<T>>。gRPC的设计初衷就是推荐使用接口类型来接收返回值,避免代码依赖具体实现类。
内容的提问来源于stack exchange,提问作者wsys

