1

I'm trying to make function that gets only int parameters. So when other types(double, char, bool) are included I used delete to exclude that like this code:

#include <iostream>

using namespace std;

int add_int(int x, int y){
    return x + y;
}

int add_int(double, double) = delete;
int add_int(int, double) = delete;
int add_int(double, int) = delete;
int add_int(bool, int) = delete; // need much more code.. very inefficient

int main(void){
    cout << add_int(1, true) << endl; // error should happen
}

But I think this is so inefficient. Is there any method like 'only int possible' or 'exclude double, char, bool(I mean input only one parameter)'?

kims
  • 85
  • 5

1 Answers1

7

Yes, you can use a function template that deletes everything.

template<class X, class Y>
int add_int(X, Y) = delete;

Now, when the compiler is resolving a function call, it will select the template unless there is a function overload where implicit type conversion is not required. An overload that requires no conversions will be selected in preference to a template function.

More information here: Overload resolution

If you like, you can also make your implementations part of this template by adding specializations:

template<>
int add_int(int x, int y)
{
    return x + y;
}
paddy
  • 60,864
  • 6
  • 61
  • 103
  • No need to provide the argument names for the deleted function template. Saves a couple of key-presses. :) – Some programmer dude Dec 08 '21 at 11:37
  • As I check the code you answered, 'template<>' is not essential. Do you have some reason to write like that? (things like convention?) – kims Dec 08 '21 at 11:42
  • 2
    @kims If you remove the `template<>` you no longer have a template specialization, but an *overload*. – Some programmer dude Dec 08 '21 at 11:46
  • 2
    Note that the presence or absence of this `template<>` will in fact produce two quite different things that happen to behave the same here. With `template<>` you're declaring a template specialization, which is considered once the primary template has been chosen by overload resolution and has deduced `X` and `Y`, and will match if both are exactly `int`. Without, you're declaring a separate (but overloading) function, which will be preferred by overload resolution if no conversion of the arguments is needed. – Quentin Dec 08 '21 at 11:47
  • @Quentin thank you, and you are right. when I use template specialization, no matter how I set up return value that value was useless. Only return value at declaration worked. – kims Dec 08 '21 at 11:54
  • I think what you're saying by "return value at declaration" is that a function template must be defined in a header. Yes, that is a well-established requirement. So indeed, if you need your implementations to be in a separate compilation unit then using the overload approach is the way to go. – paddy Dec 08 '21 at 11:59
  • @paddy full specializations *are* linkable though: you can declare `template<> int add_int(int x, int y);` and move the definition to another translation unit. – Quentin Dec 08 '21 at 12:06
  • Ahh, _that_ is cool. I learned something, cheers :) I mostly use templates like a chainsaw, rather than a chef's knife. – paddy Dec 08 '21 at 12:09