Использование g++ (Ubuntu 4.8.5-1ubuntu1) 4.8.5
и компиляции с g++ -std=c++11 -Wall -Wextra -Wconversion
станд :: функция неявное преобразование типа
Ниже не компилируется, который, как ожидалось:
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;
};
следующие компилирует с предупреждением от -Wconversion
, как и ожидалось:
void foo(float t){}
int main() {
foo(3.141592653589794626);
return 0;
}
Однако компилируется без предупреждений:
#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;
}
Очевидно, что это какое-то автоматическое преобразование float<->double
но почему это позволило в третьем примере, а не первое? Почему -Wconversion
не поймать это?
(Невидимая потеря точности является проблемой в ряде областей, например, при работе с широтой/долготой).
Спасибо Тим. После некоторого исследования ответа Эльвина Аренса я считаю, что в этом случае лучшим определением Bar является: 'template struct Bar { \t Бар (const F & foo): foo (foo) {} \t F &foo; }; '. Я не должен был использовать std :: function для начала! –
lenguador
@lenguador Будьте осторожны с этим решением. Если 'F' - это лямбда с временем жизни короче, чем созданная« Бар », вы попадете в плохие места. Я согласен с тем, что это решение обеспечивает лучшую безопасность типов, но также вызывает свернутые объявления: 'int meow (float); auto b = Bar (meow); ' –
Tim
Есть ли способ гарантировать, что функция предоставляется во время компиляции? В моем варианте использования функция известна во время компиляции, но я бы не хотел, чтобы кто-то ошибочно пропускал лямбду с неправильной продолжительностью жизни. – lenguador