Repository: microsoft/onnxruntime
File: onnxruntime/core/graph/graph.cc (C++)

Code before:
    return &node_output_types_[index];
  }

  const TensorProto* getInputData(size_t index) const override {
    auto def = node_.InputDefs()[index];
    if (!def)
      return nullptr;

    // only return data if it's for a constant initializer. checks for outer scope initializers
    // if this is a subgraph and the name isn't found locally.
    const TensorProto* initializer = graph_.GetConstantInitializer(def->Name(), true);
    return initializer;
  }

  // ORT does not implement partial data propagation yet so just return nullptr.
  const TensorShapeProto* getSymbolicInput(size_t) const override {
    return nullptr;
  }

  GraphInferencer* getGraphAttributeInferencer(const std::string& attribute_name) override {
    GraphInferencer* graph_inferencer = nullptr;

    auto* subgraph = node_.GetMutableGraphAttribute(attribute_name);

    if (subgraph) {
      auto inferencer = std::make_unique<GraphInferencerImpl>(node_, *subgraph, subgraph_inferencing_func_, options_);
      graph_inferencer = inferencer.get();
      graph_inferencers_.push_back(std::move(inferencer));
    } else {
      fail_type_inference("No Graph instance was found for attribute ",
                          attribute_name, " in node ", node_.Name());
    }

    return graph_inferencer;
  }

  // XXX: When we changed and kept sparse constant initializers in sparse form,
  // we would adjust this method
  const SparseTensorProto* getInputSparseData(size_t) const override {
    return nullptr;
  }

 private:
  Node& node_;
  // node_output_types_ will be populated by the operator-specific shape inference.
  std::vector<TypeProto> node_output_types_;
  SubgraphInferencingFunc subgraph_inferencing_func_;
  std::vector<std::unique_ptr<GraphInferencerImpl>> graph_inferencers_;
  const Graph& graph_;
  const Graph::ResolveOptions& options_;
};

Review comment (suggestion):
Using `emplace_back` is a more modern and idiomatic C++17 approach for constructing the element in-place within the vector
```diff
-          auto temp_tensor_proto = utils::TensorToTensorProto(tensor, initializer->name(), /*use_tensor_buffer=*/false);
-          // Store the temporary proto so it outlives this call, maintain pointers steady
-          temp_tensor_protos_.push_back(std::make_unique<ONNX_NAMESPACE::TensorProto>(std::move(temp_tensor_proto)));
-          return temp_tensor_protos_.back().get();
+          // Store the temporary proto so it outlives this call, maintain pointers steady.
+          // Use emplace_back to construct the unique_ptr in-place.
+          temp_tensor_protos_.emplace_back(std::make_unique<ONNX_NAMESPACE::TensorProto>(
+              utils::TensorToTensorProto(tensor, initializer->name(), /*use_tensor_buffer=*/false)));
+          return temp_tensor_protos_.back().get();
```

Code after:
    return &node_output_types_[index];
  }

  const TensorProto* getInputData(size_t index) const override {
    auto def = node_.InputDefs()[index];
    if (!def)
      return nullptr;

    // only return data if it's for a constant initializer. checks for outer scope initializers
    // if this is a subgraph and the name isn't found locally.
    const TensorProto* initializer = graph_.GetConstantInitializer(def->Name(), true);
    if (initializer != nullptr) {
      // Check if this is in-memory external data (data stored in OrtValue)
      // ONNX shape inference cannot handle external data, so we need to materialize it
      if (utils::HasExternalDataInMemory(*initializer)) {
        // Try to get the OrtValue for this initializer
        OrtValue ort_value;
        if (graph_.GetOrtValueInitializer(def->Name(), ort_value, true)) {
          // Create a temporary TensorProto with the actual data from the OrtValue
          // This allows ONNX shape inference to access the data
          const Tensor& tensor = ort_value.Get<Tensor>();
          auto temp_tensor_proto = utils::TensorToTensorProto(tensor, initializer->name(), /*use_tensor_buffer=*/false);
          // Store the temporary proto so it outlives this call, maintain pointers steady
          temp_tensor_protos_.push_back(std::make_unique<ONNX_NAMESPACE::TensorProto>(std::move(temp_tensor_proto)));
          return temp_tensor_protos_.back().get();
        } else {
          // If we can't get the OrtValue, it is a bug
          ORT_THROW("Initializer ", def->Name(),
                    " has in-memory external data but cannot get OrtValue during shape inference");
        }
      }
    }
    return initializer;
  }

  // ORT does not implement partial data propagation yet so just return nullptr.
  const TensorShapeProto* getSymbolicInput(size_t) const override {
    return nullptr;
  }

  GraphInferencer* getGraphAttributeInferencer(const std::string& attribute_name) override {
    GraphInferencer* graph_inferencer = nullptr;

    auto* subgraph = node_.GetMutableGraphAttribute(attribute_name);

    if (subgraph) {
      auto inferencer = std::make_unique<GraphInferencerImpl>(node_, *subgraph, subgraph_inferencing_func_, options_);
      graph_inferencer = inferencer.get();
      graph_inferencers_.push_back(std::move(inferencer));
    } else {
      fail_type_inference("No Graph instance was found for attribute ",