Using g++ (Ubuntu 4.8.5-1ubuntu1) 4.8.5
and compiling with g++ -std=c++11 -Wall -Wextra -Wconversion
The following does not compile which is as expected:
template <typename T>
struct Foo {
Foo(T t) {}
};
struct Bar {
Bar(Foo<float> foo) : foo(foo) {} //Trying to convert Foo<float> to Foo<double>
Foo<double> foo;
};
The following compiles with a warning from -Wconversion
, as expected:
void foo(float t){}
int main() {
foo(3.141592653589794626);
return 0;
}
However, the following compiles with no warnings:
#include <functional>
void foo(double t){}
struct Bar {
Bar(std::function<void(float)> foo) : foo(foo) {} //Convert std::function<void(float)> to std::function<void(double)>
std::function<void(double)> foo;
};
int main(){
Bar bar(foo); //Convert std::function<void(double)> to std::function<void(float)>
bar.foo(3.141592653589794626); //Rounded to: 3.141592741012573
foo(3.141592653589794626); //Not rounded: 3.141592653589794
return 0;
}
Clearly this is some automatic conversion float<->double
but why is it allowed in the third example and not the first? Why does -Wconversion
not catch this?
(Invisible loss of precision is a problem in a number of areas, for example when working with latitude/longitude).