How to prevent floating-point being implicitly converted to integral value at function call?
#include <iostream>
void fn(int x) {
std::cout<<"fn("<<x<<")\n";
}
int main() {
std::cout<<"Hello, this is 301014 :)\n";
fn(2);
fn(3.5);
return 0;
}
Here the outputs are 2 and 3 respectively.
I am compiling with g -std=c 11 31014.cpp -o 31014 -v
. And there is no mention of 3.5 being converted to 3.
Is there a way to prevent, or atleast detect, this?
Kindly help me out, please.
CodePudding user response:
There are multiple ways to handle this in c 11.
Method 1: You SFINAE the function template fn
by using std::enable_if
.
template<typename T>
typename std::enable_if<std::is_same<T, int>::value>::type fn(T x) {
std::cout << "fn(" << x << ")\n";
}
int main() {
std::cout << "Hello, this is 301014 :)\n";
fn(2); // works
// fn(3.5); // won't work;
}
Method 2: Alternatively, delete the functions using =delete
, which shouldn't take place in
template deduction.
void fn(int x) { // #1
std::cout << "fn(" << x << ")\n";
}
template<typename T> void fn(T) = delete; // #2
int main() {
std::cout << "Hello, this is 301014 :)\n";
fn(2); // works using #1
// fn(3.5); // won't work since it uses #2
}
CodePudding user response:
Another way to solve this is to add template<typename T> void fn(T)=delete;
(also works with older c standards):
#include <iostream>
template<typename T> void fn(T)=delete;
void fn(int x) {
std::cout<<"fn("<<x<<")\n";
}
int main() {
std::cout<<"Hello, this is 301014 :)\n";
fn(2);
fn(3.5); // now gives error
return 0;
}
CodePudding user response:
There are several ways to prevent implicit conversion.
Using
std::enable_if
andstd::is_same
.template <class T, std::enable_if_t<std::is_same_v<T,int>,bool> = false> void func(T x) { cout << x << endl; }
In C 20, one can use
requires
template <class T> requires std::same_as(T,int) void func(T x) { // .... }
Using
concept
.template <class T> concept explicit_int = std::same_as<T,int>; void func(explicit_int auto x) { // ... }
CodePudding user response:
Enable the right compiler warnings.
GCC and Clang call this warning -Wconversion
.
With this flag, I get:
<source>:10:8: warning: implicit conversion from 'double' to 'int' changes value from 3.5 to 3 [-Wliteral-conversion]
fn(3.5);
~~ ^~~