Q246891: BUG: Build Errors on Non-Void Return Types for Friend Function

Article: Q246891
Product(s): Microsoft C Compiler
Version(s): WINDOWS:6.0
Operating System(s): 
Keyword(s): kbtemplate kbCompiler kbLangCPP kbLinker kbVC kbVC600 kbVC600bug kbDSupport
Last Modified: 07-MAY-2001

-------------------------------------------------------------------------------
The information in this article applies to:

- Microsoft Visual C++, 32-bit Enterprise Edition, version 6.0 
-------------------------------------------------------------------------------

SYMPTOMS
========

When building an application that has a friend template function in a
nontemplated class, you may see one of the following error messages:

  error C2440: '=' : cannot convert from 'void' to 'type'
  Expressions of type void cannot be converted to other types.

  or

  error LNK2001: unresolved external symbol "void __cdecl Test(int)"
  (?Test@@YAXH@Z)

Please refer to the sample in the "More Information" section for details.

CAUSE
=====

The compiler and linker are expecting a void return type.

RESOLUTION
==========

Use one of the following two workarounds:

- Include the friend template function implementation either in header file or
  in main source file.

- Change the return type of the friend function template to void. If return
  type is important, pass it as reference.

STATUS
======

Microsoft has confirmed this to be a bug in the Microsoft products listed at the
beginning of this article.

MORE INFORMATION
================

There are two scenarios in which this error occurs.

- Case 1: When the return type of the friend function template is assigned to a
  variable, the compiler produces a C2440 error.

- Case 2: If the return type of the friend function template is not used, then
  a LNK2001 error is produced by the linker.

Steps to Reproduce Behavior
---------------------------

The following example demonstrates the error:

Create three files and compile with: cl main.cpp file.cpp

- File.h

  class A
  {
    public :
         template<class T> friend int Test(T);
  }; 

  template int Test(int); // Instantiate the template friend function explicitly.

- File.cpp

  #include "file.h"

  // Friend function implementation.
  template<class T> int  Test(T temp)
  {
  	return 0;
  }

- Main.cpp

  #include "file.h"

  //#define CASE1 
  //Uncomment the above line to reproduce Case 1. 
  //#define CASE2
  //Uncomment the above line to reproduce Case 2.

  void main()
  {

     int x =1;

  #ifdef CASE1
     int n = Test('c'); // Gives a C2440 compile error.
  #endif

  #ifdef CASE2
     Test(x); // Gives LNK2001 linker error.
  #endif

  } 

Additional query words:

======================================================================
Keywords          : kbtemplate kbCompiler kbLangCPP kbLinker kbVC kbVC600 kbVC600bug kbDSupport 
Technology        : kbVCsearch kbAudDeveloper kbVC600 kbVC32bitSearch
Version           : WINDOWS:6.0
Issue type        : kbbug
Solution Type     : kbnofix

=============================================================================