Search code examples
c++c++11c++14c++17implicit-conversion

Prevent implicit conversion for primary data types C++


BLOT: C++ has implicit conversion, I am looking for a way to prevent it.

Let me take an example for the same, for the code snippet below:

#include <iostream>

int incrementByOne(int i) {
    return ++i;
}

int main()
{
    bool b = true;
    
    std::cout << incrementByOne(b) << std::endl;

    return 0;
}

It would output: 2

How can I prevent such implicit conversions and be strict about taking only int as an argument even at runtime?

One way I can think of is overload the function. So the new code would look like:

#include <iostream>

int incrementByOne(int i) {
    return ++i;
}

int incrementByOne(bool) {
    std::cerr << "Please provide integer as argument" << std::endl;
    exit(0);
}

int incrementByOne(char) {
    std::cerr << "Please provide integer as argument" << std::endl;
    exit(0);
}

int main()
{
    bool b = true;
    
    std::cout << incrementByOne(b) << std::endl;

    return 0;
}

Is there any other(recommended) way of preventing implicit conversions at runtime?


Solution

  • You can do this with the help of template<> and the delete operator:

    #include <iostream>
    
    int incrementByOne(int x) {
        return ++x;
    }
    
    template<class T>
    T incrementByOne(T) = delete; // deleting the function
    
    int main(void) {
        std::cout << incrementByOne(-10) << std::endl;
        std::cout << incrementByOne('a') << std::endl; // will not compile
    
        return 0;
    }
    

    After this, the parameter to be passed to the function must be an integer.

    Supposing a floating point value was given in the function argument, you'll get the error:

    main.cpp: In function 'int main()':
    main.cpp:11:36: error: use of deleted function 'T incrementByOne(T) [with T = double]'
       11 |     std::cout << incrementByOne(3.5) << std::endl;
          |                                    ^