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?

General Sirhc
  • 106
  • 1
  • 7

2 Answers2

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.

  • 2
    Do not forget that, `signed int` (or `int`) != `unsigned int`. You need for *each* type a function. – Raphael Bossek Jan 05 '11 at 12:11
  • 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) – jalf Jan 05 '11 at 12:18
  • Okay thanks, its difficult choosing which answer I think it correct but I think I will choose yours because of the more in depth example – General Sirhc Jan 05 '11 at 12:31
  • @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. – CB Bailey Jan 05 '11 at 13:41
  • @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. – General Sirhc Jan 05 '11 at 14:22
  • @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. – CB Bailey Jan 05 '11 at 14:26
  • Nitpick: One might note that above code will *not* result in a "compile error" but in a linker error. – Martin Ba Sep 07 '11 at 13:26
  • 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. – David Doria Sep 11 '12 at 21:01
  • I do not get a compile error - I get a link error – Erel Segal-Halevi Mar 13 '21 at 17:25
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.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656