Jump to content

  • Log In with Google      Sign In   
  • Create Account


#ActualBrother Bob

Posted 01 September 2012 - 04:42 PM

That is not partial specialization, but regular function overloading. The two templates are separate.

I am not entirely sure about this explanation, but this is how I understand it and MSVC seems to support it as far as my testing goes at least. If you pass a pointer, then there has to be a mechanism to determine which one is called, of course, and the one with the best match is chosen. There are two things that are important:
  • A const value in a parameter is redundant and, at least as far as function prototype matching goes, equivalent to the const not being there.
  • A non-const overload is preferred over a const overload for a non-const parameter.
The meaning of point 1 is the following:
void foo(const int a);

int main()
{
	int a = ...
	foo(a);
}

void foo(int a)
{ ... }
The forward declaration of foo with a const has exactly the same prototype, as far as the parameter matching goes, as the definition of foo.

So, you have two overloaded templates: (a) one with a value parameter, and (b) one with a const-pointer parameter. If you pass a non-const int pointer, overload (a) with T=int * is in fact preferred over (b) because of point 2 above. If you have a const int pointer, then overload (b) with T=int is preferred over (a) because it's const, and the pointer-type overload is a better match than a value overload with T=int *.

So what you have is the correct way, but I suspect you're not failing to call the pointer-overload because the other overload a better match, but because you're passing a non-const pointer and non-const overloads are preferred over const-overloads in that case.

#2Brother Bob

Posted 01 September 2012 - 04:38 PM

That is not partial specialization, but regular function overloading. The two templates are separate.

I am not entirely sure about this explanation, but this is how I understand it and MSVC seems to support it as far as my testing goes at least. If you pass a pointer, then there has to be a mechanism to determine which one is called, of course, and the one with the best match is chosen. There are two things that are important:
  • A const value in a parameter is redundant and, at least as far as function prototype matching goes, equivalent to the const not being there.
  • A non-const overload is preferred over a const overload for a non-const parameter.
The meaning of point 1 is the following:
void foo(const int a);

int main()
{
	int a = ...
	foo(a);
}

void foo(int a)
{ ... }
The forward declaration of foo with a const has exactly the same prototype, as far as the parameter matching goes, as the definition of foo.

So, you have two overloaded templates: (a) one with a value parameter, and (b) one with a const-pointer parameter. If you pass a non-const int pointer, overload (a) with T=int * is in fact preferred over (b) because of point 2 above. If you have a const int pointer, then overload (b) with T=int is preferred over (a) because it's const, and the pointer-type overload is a better match than a value overload with T=int *.

So what you have is the correct way, but I suspect you're not failing to call the pointer-overload because it's a better match, but because you're passing a non-const pointer and non-const overloads are preferred over const-overloads in that case.

#1Brother Bob

Posted 01 September 2012 - 04:37 PM

That is not partial specialization, but regular function overloading. The two templates are separate.

I am not entirely sure about this explanation, but this is how I understand it and MSCV seems to support it as far as my testing goes at least. If you pass a pointer, then there has to be a mechanism to determine which one is called, of course, and the one with the best match is chose. There are two things that are important:
  • A const value in a parameter is redundant and, at least as far as function prototype matching goes, equivalent to the const not being there.
  • A non-const overload is preferred over a const overload for a non-const parameter.
The meaning of point 1 is the following:
void foo(const int a);

int main()
{
    int a = ...
    foo(a);
}

void foo(int a)
{ ... }
The forward declaration of foo with a const has exactly the same prototype, as far as the parameter matching goes, as the definition of foo.

So, you have two overloaded templates: (a) one with a value parameter, and (b) one with a const-pointer parameter. If you pass a non-const int pointer, overload (a) with T=int * is in fact preferred over (b) because of point 2 above. If you have a const int pointer, then overload (b) with T=int is preferred over (a) because it's const, and the pointer-type overload is a better match than a value overload with T=int *.

So what you have is the correct way, but I suspect you're not failing to call the pointer-overload because it's a better match, but because you're passing a non-const pointer and non-const overloads are preferred over const-overloads in that case.

PARTNERS