diff --git a/oneflow/core/actor/actor_message.cpp b/oneflow/core/actor/actor_message.cpp
index 819ffa8364c5dec0cfbd45c9bb276619f6e18248..79c871fd903f09de21ef5dc8f43a018572f6c81d 100644
--- a/oneflow/core/actor/actor_message.cpp
+++ b/oneflow/core/actor/actor_message.cpp
@@ -4,9 +4,6 @@
 
 namespace oneflow {
 
-OF_DEFINE_ENUM_TO_OSTREAM_FUNC(ActorCmd);
-OF_DEFINE_ENUM_TO_OSTREAM_FUNC(ActorMsgType);
-
 ActorMsg ActorMsg::BuildRegstMsgToConsumer(int64_t producer, int64_t consumer,
                                            Regst* regst_raw_ptr) {
   ActorMsg msg;
diff --git a/oneflow/core/actor/actor_message.h b/oneflow/core/actor/actor_message.h
index a653a6060ecc547421305d8a6226dacf7b3a2395..76e26583d992ecdcb892d7c8e3b4feedcdd6d5f9 100644
--- a/oneflow/core/actor/actor_message.h
+++ b/oneflow/core/actor/actor_message.h
@@ -14,12 +14,8 @@ enum class ActorCmd {
   kConstructActor
 };
 
-OF_DECLARE_ENUM_TO_OSTREAM_FUNC(ActorCmd);
-
 enum class ActorMsgType { kRegstMsg = 0, kEordMsg, kCmdMsg };
 
-OF_DECLARE_ENUM_TO_OSTREAM_FUNC(ActorMsgType);
-
 class ActorMsg final {
  public:
   // OF_DISALLOW_COPY_AND_MOVE(ActorMsg);
diff --git a/oneflow/core/comm_network/ibverbs/ibverbs_comm_network.cpp b/oneflow/core/comm_network/ibverbs/ibverbs_comm_network.cpp
index 7269beeb6c6ab5c7fbee180de2068823b3fd35f7..c2dd48001ec123223ca50765ffef3af6711ba096 100644
--- a/oneflow/core/comm_network/ibverbs/ibverbs_comm_network.cpp
+++ b/oneflow/core/comm_network/ibverbs/ibverbs_comm_network.cpp
@@ -7,8 +7,6 @@ namespace oneflow {
 
 namespace {
 
-OF_DEFINE_ENUM_TO_OSTREAM_FUNC(ibv_wc_status);
-
 std::string GenTokensMsgKey(int64_t machine_id) {
   return "IBVerbsTokensMsg/" + std::to_string(machine_id);
 }
diff --git a/oneflow/core/common/util.h b/oneflow/core/common/util.h
index 90c0263ff0293ddc8caa556dd65364849a3a9bd9..67f22dcb783609412d98f1aec2187e930627fef7 100644
--- a/oneflow/core/common/util.h
+++ b/oneflow/core/common/util.h
@@ -131,14 +131,12 @@ void EraseIf(HashMap<K, V>* hash_map, std::function<bool(typename HashMap<K, V>:
   }
 }
 
-#define OF_DECLARE_ENUM_TO_OSTREAM_FUNC(EnumType) \
-  std::ostream& operator<<(std::ostream& out_stream, const EnumType&)
-
-#define OF_DEFINE_ENUM_TO_OSTREAM_FUNC(EnumType)                          \
-  std::ostream& operator<<(std::ostream& out_stream, const EnumType& x) { \
-    out_stream << static_cast<int>(x);                                    \
-    return out_stream;                                                    \
-  }
+template<typename T>
+typename std::enable_if<std::is_enum<T>::value, std::ostream&>::type operator<<(
+    std::ostream& out_stream, const T& x) {
+  out_stream << static_cast<int>(x);
+  return out_stream;
+}
 
 template<typename OutType, typename InType>
 OutType oneflow_cast(const InType&);
diff --git a/oneflow/core/control/ctrl_client.cpp b/oneflow/core/control/ctrl_client.cpp
index dd9885c0b8c4c1d9aa477d071b589ba3b4976ae0..3e5a39e96f41d86e798958561d89b59fefef7a54 100644
--- a/oneflow/core/control/ctrl_client.cpp
+++ b/oneflow/core/control/ctrl_client.cpp
@@ -8,8 +8,6 @@ namespace {
 const int32_t max_retry_num = 60;
 const int64_t sleep_seconds = 10;
 
-OF_DEFINE_ENUM_TO_OSTREAM_FUNC(grpc::StatusCode);
-
 #define GRPC_CHECK(x) CHECK_EQ(x.error_code(), grpc::StatusCode::OK)
 
 #define DEFINE_CLIENT_CALL(method)                                 \