diff --git a/include/grpc++/impl/codegen/call.h b/include/grpc++/impl/codegen/call.h index f6eefb9f7ff..33d8f4ce65e 100644 --- a/include/grpc++/impl/codegen/call.h +++ b/include/grpc++/impl/codegen/call.h @@ -349,6 +349,28 @@ class CallOpRecvMessage { bool allow_not_getting_message_; }; +namespace CallOpGenericRecvMessageHelper { +class DeserializeFunc { + public: + virtual Status Deserialize(grpc_byte_buffer* buf) = 0; + virtual ~DeserializeFunc() {} +}; + +template +class DeserializeFuncType final : public DeserializeFunc { + public: + DeserializeFuncType(R* message) : message_(message) {} + Status Deserialize(grpc_byte_buffer* buf) override { + return SerializationTraits::Deserialize(buf, message_); + } + + ~DeserializeFuncType() override {} + + private: + R* message_; // Not a managed pointer because management is external to this +}; +} // namespace CallOpGenericRecvMessageHelper + class CallOpGenericRecvMessage { public: CallOpGenericRecvMessage() @@ -356,9 +378,11 @@ class CallOpGenericRecvMessage { template void RecvMessage(R* message) { - deserialize_ = [message](grpc_byte_buffer* buf) -> Status { - return SerializationTraits::Deserialize(buf, message); - }; + // Use an explicit base class pointer to avoid resolution error in the + // following unique_ptr::reset for some old implementations. + CallOpGenericRecvMessageHelper::DeserializeFunc* func = + new CallOpGenericRecvMessageHelper::DeserializeFuncType(message); + deserialize_.reset(func); } // Do not change status if no message is received. @@ -381,7 +405,7 @@ class CallOpGenericRecvMessage { if (recv_buf_) { if (*status) { got_message = true; - *status = deserialize_(recv_buf_).ok(); + *status = deserialize_->Deserialize(recv_buf_).ok(); } else { got_message = false; g_core_codegen_interface->grpc_byte_buffer_destroy(recv_buf_); @@ -392,12 +416,11 @@ class CallOpGenericRecvMessage { *status = false; } } - deserialize_ = DeserializeFunc(); + deserialize_.reset(); } private: - typedef std::function DeserializeFunc; - DeserializeFunc deserialize_; + std::unique_ptr deserialize_; grpc_byte_buffer* recv_buf_; bool allow_not_getting_message_; };