Search code examples
c++bnf

why primary expression don't include template_id


I have such code, compile with "g++ -Wall -g -std=c++11 test.cpp ",which doesn't compile because error: expected primary-expression before ‘)’ token

#include <functional>
#include <vector>
#include <algorithm>

int main()
{
  std::vector<int> vec;
  for(int i=0;i<10;++i)
    {
      vec.push_back(i);
    }
  std::sort(vec.begin(),vec.end(),std::less<int>);  //should be std::less<int>()
}

But the standard says:

primary-expression:
  literal
  this
  ( expression )
  id-expression
  lambda-expression

id-expression:
  unqualified-id
  qualified-id

unqualified-id:
  identifier
  operator-function-id
  conversion-function-id
  literal-operator-id
  ~ class-name
  ~ decltype-specifier
 template-id

template-id
  simple-template-id

simple-template-id
  template-name <template-argument-list> 

So it seems std::less is a template-id, so it's a primary-expression.


Solution

  • Being grammatically correct doesn't necessarily make the program semantically correct. The grammar production from primary-expression -> template-id is there to allow use of a specialization of a function template as an expression, e.g, this is valid:

    template <typename T>
    bool less(const T& a, const T& b) { return a < b; }
    
    int main() {
      std::vector<int> vec;
      std::sort(vec.begin(), vec.end(), less<int>);
    }
    

    A template-id that refers to a class template, however, is not usable as an expression.