g++ (Ubuntu 4.8.5-1ubuntu1) 4.8.5
Verwendung und Kompilieren mit g++ -std=c++11 -Wall -Wextra -Wconversion
std :: function implizite Typumwandlung
Die folgenden nicht kompiliert, die wie erwartet:
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;
};
Folgende compiliert mit einer Warnung von -Wconversion
, wie erwartet:
Die folgenden kompiliert jedoch mit keine Warnungen:
#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;
}
Offensichtlich ist dies eine automatische Konvertierung float<->double
aber warum ist es in dem dritten Beispiel erlaubt und nicht die erste? Warum fängt -Wconversion
das nicht?
(Unsichtbar Genauigkeitsverlust ein Problem in einer Reihe von Bereichen, beispielsweise wenn mit dem Breitengrad/Längengrad arbeiten).
Danke Tim. Nach einigen Recherchen von Antwort Elwin Arens ich in diesem Fall die beste Definition von Bar glauben ist: 'template struct Bar { \t Bar (const F & foo): foo (foo) {} \t F &foo; }; '. Ich hätte nicht mit der std :: -Funktion anfangen sollen! –
lenguador
@lenguador Seien Sie vorsichtig mit dieser Lösung. Wenn 'F' ein Lambda mit einer Lebenszeit ist, die kürzer ist als die'Bar', die instanziiert wird, werden Sie an schlechte Stellen gehen. Ich stimme zu, dass diese Lösung für eine bessere Typensicherheit sorgt, aber auch verworrene Erklärungen liefert: "int meow (float); auto b = Balken (meow); ' –
Tim
Gibt es eine Möglichkeit, sicherzustellen, dass eine Funktion zur Kompilierzeit bereitgestellt wird? In meinem Anwendungsfall ist die Funktion zur Kompilierzeit bekannt, aber ich möchte nicht, dass jemand fälschlicherweise ein Lambda mit einer falschen Lebenszeit übergibt. – lenguador