title: Illegal use of type as an expression
body: <p>I've got a nasty problem with some code and can't see the error. I have a template function</p>
  
  <pre><code>template&lt;typename T, typename F&gt; void RecursiveParseLeftAssociativeBinaryExpression(std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt;&amp; cur_expr, F f) {
      CheckedIncrement();
      auto new_expr = Wide::make_unique&lt;T&gt;();
      new_expr-&gt;lhs = std::move(cur_expr);
      new_expr-&gt;rhs = f();
      cur_expr = std::move(new_expr);
  }
  </code></pre>
  
  <p>with the obvious implementation of <code>make_unique</code>. There are other overloads, but they differ in obvious ways like different parameter numbers, so I know that this is the only one being called. Then I call it, like so (this is the error line, 315):</p>
  
  <pre><code>RecursiveParseLeftAssociativeBinaryExpression&lt;Wide::Parser::AccessExpression&gt;(current_expression, [&amp;] { return this_ptr-&gt;RecursiveParseExpression(); });
  </code></pre>
  
  <p>But the compiler insists that I am using a type as an expression. I'm pretty sure that this code is completely legal. Am I missing something? The error is </p>
  
  <pre><code>1&gt;parser.cpp(315): error C2275: 'Wide::Parser::AccessExpression' : illegal use of this type as an expression
  </code></pre>
  
  <p>Edit: These are the definitions of the other overloads.</p>
  
  <pre><code>template&lt;typename First, Wide::Lexer::TokenType first, typename F&gt; std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt; RecursiveParseLeftAssociativeBinaryExpression(F next) {
      auto cur_expr = next();
      std::function&lt;void()&gt; RecursiveParseSingleToken;
      RecursiveParseSingleToken = [&amp;] {
          switch(begin-&gt;type) {
          case first:
              RecursiveParseLeftAssociativeBinaryExpression&lt;First&gt;(cur_expr, next);
              return RecursiveParseSingleToken();
          }
      };
      RecursiveParseSingleToken();
      return std::move(cur_expr);
  }
  
  template&lt;typename First, typename Second, Wide::Lexer::TokenType first, Wide::Lexer::TokenType second, typename F&gt; std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt;
  RecursiveParseLeftAssociativeBinaryExpression(F next) {
      auto cur_expr = next();
      std::function&lt;void()&gt; RecursiveParseDualToken;
      RecursiveParseDualToken = [&amp;] {
          switch(begin-&gt;type) {
          case first:
              RecursiveParseLeftAssociativeBinaryExpression&lt;First&gt;(cur_expr, next);
              return RecursiveParseDualToken();
          case second:
              RecursiveParseLeftAssociativeBinaryExpression&lt;Second&gt;(cur_expr, next);
              return RecursiveParseDualToken();
          }
      };
      RecursiveParseDualToken();
  
      return std::move(cur_expr);
  }
  </code></pre>
  
  <p>However, they clearly differ in requiring additional explicit template arguments, and so cannot be the call resolved.</p>
  
  <p>Edit: The definition of <code>make_unique</code>:</p>
  
  <pre><code>namespace Wide {
      template&lt;typename T&gt; std::unique_ptr&lt;T&gt; make_unique() {
          return std::unique_ptr&lt;T&gt;(new T);
      }
  };
  </code></pre>
  
  <p>Just to be certain, the calling code isn't in any template of any kind, and there are absolutely no dependent names. <code>Wide</code> is a namespace.</p>
  
  <p>Another edit: The error is repeated for all the direct calls to this overload, but <em>not</em> for the ones which are called through the other overloads, curiously.</p>
  
  <p>Edit: This 100line test case reproduces the problem.</p>
  
  <pre><code>#include &lt;memory&gt;
  #include &lt;functional&gt;
  #include &lt;vector&gt;
  
  namespace Wide {
      template&lt;typename T&gt; std::unique_ptr&lt;T&gt; make_unique() {
          return std::unique_ptr&lt;T&gt;(new T);
      }
      class Lexer {
      public:
          enum TokenType {
              Namespace,
              For,
              Identifier
          };
          struct Token {
              TokenType type;
          };
      };
      class Parser {
      public:
          struct ExpressionAST {};
          struct BinaryExpressionAST : public ExpressionAST {
              std::unique_ptr&lt;ExpressionAST&gt; lhs;
              std::unique_ptr&lt;ExpressionAST&gt; rhs;
          };
          struct AccessExpression : public BinaryExpressionAST {};
          struct IdentifierExpression : public ExpressionAST {};
      };
  }
  
  typedef std::vector&lt;Wide::Lexer::Token&gt;::iterator Iterator;
  
  struct inner_parser {
      Iterator begin, end;
  
      std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt; RecursiveParsePrimaryExpression() {
          if (begin-&gt;type == Wide::Lexer::TokenType::Identifier) {
              CheckedIncrement();
              return Wide::make_unique&lt;Wide::Parser::IdentifierExpression&gt;();
          }
          throw std::runtime_error("aah");
      }
      template&lt;typename T, typename F&gt; void RecursiveParseLeftAssociativeBinaryExpression(std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt;&amp; cur_expr, F f) {
          CheckedIncrement();
          auto new_expr = Wide::make_unique&lt;T&gt;();
          new_expr-&gt;lhs = std::move(cur_expr);
          new_expr-&gt;rhs = f();
          cur_expr = std::move(new_expr);
      }
      template&lt;typename First, Wide::Lexer::TokenType first, typename F&gt; std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt;
      RecursiveParseLeftAssociativeBinaryExpression(F next) {
          auto cur_expr = next();
          std::function&lt;void()&gt; RecursiveParseSingleToken;
          RecursiveParseSingleToken = [&amp;] {
              switch(begin-&gt;type) {
              case first:
                  RecursiveParseLeftAssociativeBinaryExpression&lt;First&gt;(cur_expr, next);
                  return RecursiveParseSingleToken();
              }
          };
          RecursiveParseSingleToken();
          return std::move(cur_expr);
      }
  
      template&lt;typename First, typename Second, Wide::Lexer::TokenType first, Wide::Lexer::TokenType second, typename F&gt;
      std::unique_ptr&lt;Wide::Parser::ExpressionAST&gt;
          RecursiveParseLeftAssociativeBinaryExpression(F next) {
              auto cur_expr = next();
              std::function&lt;void()&gt; RecursiveParseDualToken;
              RecursiveParseDualToken = [&amp;] {
                  switch(begin-&gt;type) {
                  case first:
                      RecursiveParseLeftAssociativeBinaryExpression&lt;First&gt;(cur_expr, next);
                      return RecursiveParseDualToken();
                  case second:
                      RecursiveParseLeftAssociativeBinaryExpression&lt;Second&gt;(cur_expr, next);
                      return RecursiveParseDualToken();
                  }
              };
              RecursiveParseDualToken();
  
              return std::move(cur_expr);
      }
  
      void CheckedIncrement() {
          if (begin == end)
              throw std::runtime_error("aaaaaah!");
          begin++;
      }
  };
  int main() {
      std::vector&lt;Wide::Lexer::Token&gt; tokens;
      inner_parser ip;
      ip.begin = tokens.begin();
      ip.end = tokens.end();
      auto ret = ip.RecursiveParseLeftAssociativeBinaryExpression&lt;Wide::Parser::AccessExpression, Wide::Lexer::TokenType::For&gt;([&amp;] { return ip.RecursiveParsePrimaryExpression(); });
      return 0;
  }
  </code></pre>