Click here to Skip to main content
15,889,861 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
When I overload a class's member function solely on the const qualifier of the parameter (which is a different class's member function pointer), the compiler resolves the overload and performs as expected.
When I attempt the same overload for a non-member function, the compiler (VS2010 Express) complains of linker errors.

Does anyone know why ?

C++
//Header.h

#pragma once

#include "targetver.h"
#include <stdio.h>
#include <tchar.h>
#include <iostream>

struct Component
{
	int Execute(bool X) { return 0; }

	int ConstExecute(bool X) const { return 0; }
};

struct Tester
{
	void Con( int (Component::*MFP)(bool) )
	{ std::cout << "Tester::Con Passed Non-Const MFP\n"; };

	void Con( int (Component::*MFP)(bool) const )
	{ std::cout << "Tester::Con Passed Const MFP\n"; };
};


void Con( int (Component::*MFP)(bool) )
{ std::cout << "Con Passed Non-Const MFP\n"; };

void Con( int (Component::*MFP)(bool) const )
{ std::cout << "Con Passed Const MFP\n"; };


//Main.cpp

#include "Header.h"

int _tmain(int argc, _TCHAR* argv[])
{	
	// In Main
	Tester MyTester;
	MyTester.Con( &Component::Execute );
	MyTester.Con( &Component::ConstExecute );

	Con( &Component::Execute );
        // LNK2005: Con(int (__thiscall Component::*)(bool) already defined
	Con( &Component::ConstExecute );
        // LNK2005: Con(int (__thiscall Component::*)(bool)const ) already defined

	char X;
	std::cin >> X;
	return 0;
}


Commenting out the calls to the non-member Con Function produces:
"Tester::Con Passed Non-Const MFP"
"Tester::Con Passed Const MFP"
as expected.
Posted
Updated 6-Nov-11 23:17pm
v3
Comments
Andrew Brock 7-Nov-11 5:33am    
This may be a limitation of the Express compiler.
I just ran this code (minus a few #includes) on VS2010 Ultimate with Service Pack 1. It worked as you would expect.

Ignore my comment. I wasn't thinking straight.

The issue is that this code is defined in a header file.
This means that for every .cpp file that includes this, the function code is defined (under the same name).

The #pragma once only stops this file getting included more than once by any 1 cpp file, it doesn't stop it getting included my multiple files.

Either give the function prototype in the header, and define the code in just 1 cpp file, or add the inline keyword to the start of the functions
C++
inline void Con( int (Component::*MFP)(bool) )
{ std::cout << "Con Passed Non-Const MFP\n"; };
 
inline void Con( int (Component::*MFP)(bool) const )
{ std::cout << "Con Passed Const MFP\n"; };


The inline keyword makes the compiler essentially copy and paste the function code everywhere the function is called, without defining an actual function. This is a bit of a hack up, but works.
 
Share this answer
 
Comments
WodgerDodger 7-Nov-11 5:44am    
Ahhh....of course.
I was the one who wasn't thinking strait.
Thankyou very much.
;-)
Stefan_Lang 7-Nov-11 6:04am    
It's got nothing to do with where it is defined, and #pragma once won't change that (although it might fix other problems).

Using inline might work around the actual problem, depending on the compiler, but it doesn't solve it either.

In fact, what the OP intended is not possible at all: See my solution below.
There is no inherent meaning when you define a non-member function const. In a class, a member function that is declared const means that it won't change the instance of the class you call it on. For a non-member function that makes no sense however! There is no 'instance' of a class that a non-member functino relates to, therefore a const qualifier is not possible. IMHO the compiler (not the linker!) should even issue an error.

You can make an overload based on the constness of a function's parameters though.

In short, you can not overload non-member functions by adding a const qualifier to the function, only by adding them to the parameters.



P.S.: ignore this, it's just a result of my bad reading skills...
 
Share this answer
 
v2
Comments
Andrew Brock 7-Nov-11 6:08am    
Your answer is correct, it just isn't relevant to this question.
The 2 functions both non-const (also the 2 in the Tester struct), they just take a different argument, either of a const or a non-const function. It is the function which he is passing in as a parameter that has the const/non-const.
His code is perfectly valid and makes sense (although I don't imagine it is particularly useful for most scenarios).

What I said in my answer is still correct, and since it was marked as the solution I imagine it fixed the issue.
Stefan_Lang 7-Nov-11 6:18am    
Ah, I got confused by the brackets, thinking the function was const-qualified. I somehow only focused on ') const' and completely ignored everything to the left and right of that part...

After rereading your answer in light of that insight, it makes a lot more sense.
Andrew Brock 7-Nov-11 6:20am    
It took me a bit to get that too (see my comment to the original question). The code does look a bit messy

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900