templates mit mehreren Rückgabe Typen
-
Ich versteh nicht ganz was ein
throwin dieser Funktion zu suchen hat, das ist ja kein runtime error. Ich würde hier einfach die Funktion spezialisieren (wie schon von anderen angemerkt):template< class T > T get( const std::string & ) { static_assert( sizeof( T ) == 0 , "get< T > - unsupported Type" ); } template<> int get< int >( const std::string & ) { //... } template<> bool get< bool >( const std::string & ) { //... }Warum Funktionstemplates nicht spezialisieren sollte hängt mit der overload resolution zu tun, und die spielt hier ja keine Rolle.
-
wxSkip schrieb:
cooky451 schrieb:
Nein, das ist ein klassischer Fall für verschiedene Funktionen. Das Template bringt hier nur Nachteile.
Außer, er will es aus einem anderen Template heraus benutzen.
Ok, dann ist eine Spezialisierung wie bei GorbGorb aber immer noch sinnvoller.
(Außer dass ich nicht ganz verstehe, warum er nicht gleich static_assert(false, ..) schreibt. ;))
-
struct Settings { std::string str_data; int data; }; Settings* findSetting(const std::string&); template <typename T> struct type2member; template <> struct type2member<int> : std::integral_constant<int Settings::*, &Settings::data> {}; template <> struct type2member<bool> : std::integral_constant<int Settings::*, &Settings::data> {}; template <> struct type2member<std::string> : std::integral_constant<std::string Settings::*, &Settings::str_data> {}; template <typename T> T get(const std::string& name) { return findSetting(name)->*type2member<T>::value; } template <typename T> void set(const std::string& name, const T& v) { findSetting(name)->*type2member<T>::value = v; }Solange nicht noch extra Umwandlungen im Spiel sind, wird hier nur eine Zuordnung Typ->Member benötigt.
-
cooky451 schrieb:
(Außer dass ich nicht ganz verstehe, warum er nicht gleich static_assert(false, ..) schreibt. ;))
Weil der static_assert dann auch ausgelöst wird, wenn man gar nichts instanziert.
-
type_info ist hier ja mal sowas von falsch...
-
314159265358979 schrieb:
type_info ist hier ja mal sowas von falsch...
Qualitativ hochwertiger Kommentar

Es gibt Gründe, warum ich die Spezialisierung von Template-Funktionen meide...
Wenn Experten, die fast so viel Ahnung von C++ haben wie du
, davon abraten, dann nehm ich mir das zu Herzen: http://www.gotw.ca/publications/mill17.htmAlso halt einfach die Fresse, solange keiner "Arsch öffne dich" sagt oder begründe deine Ansichten...
-
Weil du ein vollständig zur Kompilezeit bekanntes Problem zur Laufzeit erst löst. Sowas hätte selbst dir auffallen können, Schlaumeier.
-
314159265358979 schrieb:
type_info ist hier ja mal sowas von falsch...
314159265358979 schrieb:
Weil du ein vollständig zur Kompilezeit bekanntes Problem zur Laufzeit erst löst. Sowas hätte selbst dir auffallen können, Schlaumeier.
Wobei das eine nichts mit dem anderen zu tun hat.
-
Blahblah, du weißt ganz genau wie's gemeint ist. Stell dich nicht dumm.
-
314159265358979 schrieb:
Weil du ein vollständig zur Kompilezeit bekanntes Problem zur Laufzeit erst löst. Sowas hätte selbst dir auffallen können, Schlaumeier.

314159265358979 schrieb:
Blahblah, du weißt ganz genau wie's gemeint ist. Stell dich nicht dumm.
Ich jedenfalls stelle mich nicht dumm, sondern weiß wirklich nicht, wie es gemeint ist.
Wieso wird die type_info zur Laufzeit ausgewertet? (Ernst gemeinte Frage...)
Das assert statt Exception sehe ich absolut ein. Ich hab die Exception nur aus seinem Code übernommen ohne mir darüber Gedanken zu machen.
Aber wenn man ein Vorgehen kritisiert und als Argument eine andere Sache nimmt, die nichts damit zu tun hat, dann stimmt irgendwas nicht.Ich bin eigentlich fest davon überzeugt, dass die type_info zur Kompilierzeit ausgewertet wird, lasse mich aber gerne eines Besseren belehren.
Alles andere würde mich jedoch sehr wundern...
-
XSpille schrieb:
Ich bin eigentlich fest davon überzeugt, dass die type_info zur Kompilierzeit ausgewertet wird, lasse mich aber gerne eines Besseren belehren.
Der
typeid-Operator ist Bestandteil von RTTI = Runtime Type Identification. Er wird schliesslich primär eingesetzt, um an den dynamischen Typen hinter Basisklassenverweisen zu kommen, welche per Definition erst zur Laufzeit feststehen.
-
Ach, ich sehe schon das Problem. Du hast deine Klasse dummerweise type_info genannt, worauf ich mir den Code nicht mehr genauer angesehen habe. Wer gibt seiner Klasse auch so einen Namen, wobei sie damit nicht mal ansatzweise was zu tun hat. Was du da verwendest, ist ein Type2Type von Alexandrescu, das passt schon so.
-
Nexus schrieb:
XSpille schrieb:
Ich bin eigentlich fest davon überzeugt, dass die type_info zur Kompilierzeit ausgewertet wird, lasse mich aber gerne eines Besseren belehren.
Der
typeid-Operator ist Bestandteil von RTTI = Runtime Type Identification. Er wird schliesslich primär eingesetzt, um an den dynamischen Typen hinter Basisklassenverweisen zu kommen, welche per Definition erst zur Laufzeit feststehen.type_info != std::type_info
Der Name mag etwas ungünstig gewählt sein für ein tag, mit RTTI hat es jedenfalls nichts zu tun.
-
Nexus schrieb:
XSpille schrieb:
Ich bin eigentlich fest davon überzeugt, dass die type_info zur Kompilierzeit ausgewertet wird, lasse mich aber gerne eines Besseren belehren.
Der
typeid-Operator ist Bestandteil von RTTI = Runtime Type Identification. Er wird schliesslich primär eingesetzt, um an den dynamischen Typen hinter Basisklassenverweisen zu kommen, welche per Definition erst zur Laufzeit feststehen.Hi Nexus,
das weiß ich.@PI: Geht deine Kritik an die typeid oder an das typeinfo-Template, das ich gepostet habe?
Ich dachte der Kommentar hatte sich auf das Template bezogen.
EDIT: OK, alle Unklarheiten beseitigt. Dann gebe ich dir absolut recht.
-
2
-
314159265358979 schrieb:
2

Also doch an das Template?

-
Ich hab die Exception nur aus seinem Code übernommen ohne mir darüber Gedanken zu machen.
nu ja möglicherweise ist die exception da nicht geeignet. Grundsätzlich soll diese mich schnell über einen Programmierfehler informieren. ich habe die komplette app in ein try gelegt.
also so:
#include "main.h" #include <QString> #include <QApplication> #include "app.h" #include "exception.h" int main(int argc, char** argv) { QApplication app(argc, argv); app.setWindowIcon(QIcon(":/tmb.ico")); QString app_style = "QMenuBar::item {background-color: rgb(255,255,255);}" "QMenuBar::item:selected {border: 1px solid rgb(121,152,241);}" "QMenu::item {padding: 2px 25px 2px 20px;background: #FFFFFF;border: 1px solid transparent;}" "QMenu::item:selected {border: 1px solid rgb(121,152,241);background-color: rgb(226,233,254);color: #000000;}" "QMenu::separator { width: 1px; height: 1px;}"; app.setStyleSheet(app_style); QString app_dir = QApplication::applicationFilePath(); app_dir = app_dir.left(app_dir.lastIndexOf( '/' ) + 1); try { return App(app, app_dir).Run(); } catch (const Exception& exception) { return exception.handle(); } }
-
Ein static_assert, fliegt aber schon beim Kompilieren auf die Nase

Sie informiert dich also schneller als eine Exception
-
ja stimmt, das ist ja schon zur compile Zeit bekannt. habe c++0x hinzugefügt
template <typename T> struct IsInteger { static bool const value = false; }; template <> struct IsInteger<int> { static bool const value = true; }; template <typename T> struct IsBool { static bool const value = false; }; template <> struct IsBool<bool> { static bool const value = true; }; template <typename T> struct IsQString { static bool const value = false; }; template <> struct IsQString<QString> { static bool const value = true; }; static_assert(IsInteger<T>::value | IsBool<T>::value | IsQString<T>::value , "unsupported type of setting");
-
Wie wäre es mit:
static_assert(std::is_same<T, int>::value || std::is_same<T, bool>::value || std::is_same<T, QString>::value, "unsupported type of setting");