Search code examples
templatescaffe2

Explanation of template statement in Caffe2 InputIsType method


The Caffe2 framework includes the following code in the file caffe2/core/operator.h:

  template <typename T>
  inline bool InputIsType(int idx) {
     return inputs_.at(idx)->template IsType<T>();
  }

I do not understand the third line of this code snippet: why is the template statement used here? To my knowledge, template is always followed by <> and used to define a type T, like in the first line of this code snippet.

Why do we need to write template before calling IsType<T>()?


Solution

  • The InputIsType method is part of the OperatorBase class, which is the base class of all operators in Caffe2. Each operator contains (among others) the following private fields (defined in caffe2/core/operator.h):

    vector<const Blob*> inputs_;
    vector<Blob*> outputs_;
    

    These are the inputs and outputs of your operator. As an operator can have multiple inputs and/or multiple outputs, both are vectors.

    The InputIsType method takes an input int idx, which defines which input Blob to look at (i.e. InputIsType(0) is the zero'th input Blob, and so on) and compares the type of that specific Blob to the type <T>. This is done using the IsType method of the Blob class, which is defined in caffe2/core/blob.h:

    /**
     * Checks if the content stored in the blob is of type T.
     */
    template <class T>
    bool IsType() const { return meta_.Match<T>(); }
    

    Note: This matches the type T to the type of our Blob. I won't go into details on how that works. Let's just assume this returns True or False as required.

    So, to check if a Blob A has type int, we would have to call

    A->IsType<int>();
    

    However, as described in this answer, the compiler doesn't know whether you want to use the template with <int> here, or whether you are doing a comparison with the < (less than) sign. So we must tell the compiler we are using templates here, and call

    A->template IsType<int>();
    

    The same applies in the case of the InputIsType method: instead of using int in this example, we use the type T (which we defined before), and call IsType on element idx of the vector inputs_:

    inputs_.at(idx)->template IsType<T>();