Stopping function implicit conversion
Asked Answered
E

2

5

I came across a strange situation today where I needed a function to not implicitly convert values.

After some looking on google I found this http://www.devx.com/cplus/10MinuteSolution/37078/1954

But I thought it was a bit stupid to use a function overload for every other type I want to block so instead I did this.


void function(int& ints_only_please){}

int main() { char a=0; int b=0; function(a); function(b); }

I showed the code to a friend and he suggested I added const before int so the variable isn't editable, however when I did started compiling fine but it shouldn't, look below to see what I mean


void function(const int& ints_only_please){}

int main() { char a=0; int b=0; function(a); //Compiler should stop here but it doesn't with const int function(b); }

Does anyone know why this is?

Exile answered 5/1, 2011 at 11:52 Comment(1)
char is implicitly convertible to intMarnamarne
G
16

Use templates to get the desired effect:

template <class T>
void foo(const T& t);

template <>
void foo<int>(const int& t)
{

}

int main(){
  foo(9); // will compile
  foo(9.0); // will not compile
  return 0;
}

Note that we only write a special version of the template for int so that a call that has any other type as a template parameter will result in a compile error.

Glori answered 5/1, 2011 at 11:56 Comment(9)
Do not forget that, signed int (or int) != unsigned int. You need for each type a function.Reta
You could couple it with some SFINAE trickery (like boost::enable_if to selectively allow multiple related types (like signed as well as unsigned int, for example)Farming
Okay thanks, its difficult choosing which answer I think it correct but I think I will choose yours because of the more in depth exampleExile
@General Sirhc: I must have misunderstood the question. The only question that you asked directly was "Does anyone know why this is?" which this answer doesn't directly address.Recursion
@Charles Bailey: No actually you completely understood the question and you answered it correctly too. I selected Grigory's answer to be correct because it was more helpful. If you would like I will mark yours as the correct answer instead? seeing as you did have the correct answer.Exile
@General Sirhc: No that's fine. I just wanted to check that I understood. If I misunderstood there would be no point keeping my answer up. I'll leave it for reference now, though.Recursion
Nitpick: One might note that above code will not result in a "compile error" but in a linker error.Resurrection
Is there a way to do it without adding this template function? If I have a whole bunch of functions that I want to do this with, doubling the number of functions to maintain sounds like a bad plan.Dennadennard
I do not get a compile error - I get a link errorAleris
R
7

It is legal to bind a temporary to a const reference, but not a non-const reference.

A char can be implicitly converted to an int and the temporary that is the result of this conversion can be bound to a const int& function parameter extending the temporary's lifetime until the function exits.

Recursion answered 5/1, 2011 at 11:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.