2017-09-06 2 views
1

Wenn habe folgendes ProblemTemplat-Alias ​​für Elementfunktionen mit unterschiedlichen Rückgabetypen

class a; 
    class b; 
    class c; 
    class db { 
     ... 
     const std::set<a*>& get_all_a(); 
     const std::vector<b*>& get_all_b(); 
     const custom_c_container& obtain_all_the_cs(); 
     ... 
    } 

ich eine lange Funktion habe, die ähnlich etwas tun muß (ich eine Vorlage schreiben kann, die den Typen a nimmt, b oder c, dafür) für jeden dieser 3 Datensätze und hat eine Instanz von db. Das einzige Problem ist der Datenzugriff. Ich möchte, dass lösen, indem sie etwas in der Art des Schreibens:

template<class data_type> 
    auto get_data(); 

    template<> 
    std::result_of<decltype(&db::get_all_a)(db)>::type get_data<a> 
     = std::mem_fn(&db::get_all_a); 

Es gibt wahrscheinlich mehrere Gründe dies nicht, aber ich hoffe, es zeigt, was ich versuche zu erreichen.

Wie vorgeschlagen I werde ein gewünschtes Verwendungsbeispiel hinzuzufügen:

template<class data_type> 
    void process(db& my_db) { 
     for(auto& item : get_data<data_type>(my_db) { 
      //... some processing ... 
     } 
    } 
    ... 
    void process_all() { 
     db my_db = get_db(); 
     process<a>(my_db); 
     process<b>(my_db); 
     process<c>(my_db); 
    } 
+1

Unklar. Zeigen Sie ein echtes Minimalbeispiel, zeigen Sie die gewünschte Syntax an. –

Antwort

1

C++ 17-Lösung:

template <class data_type> 
decltype(auto) get_data() 
{ 
     if constexpr(std::is_same_v<data_type, a>) { return get_all_a(); } 
    else if constexpr(std::is_same_v<data_type, b>) { return get_all_b(); } 
    else           { return get_all_c(); } 
} 

C++ 14-Lösung:

template <typename> 
struct dispatch; 

template <> 
struct dispatch<a> { decltype(auto) get(db& x) { return x.get_all_a(); } }; 

template <> 
struct dispatch<b> { decltype(auto) get(db& x) { return x.get_all_b(); } }; 

template <> 
struct dispatch<c> { decltype(auto) get(db& x) { return x.get_all_c(); } }; 

template <class data_type> 
decltype(auto) get_data() 
{ 
    return dispatch<data_type>{}.get(db); 
} 

C++ 11 Lösung:

template <typename> 
struct dispatch; 

template <> 
struct dispatch<a> 
{ 
    auto get(db& x) -> decltype(x.get_all_a()) { return x.get_all_a(); } 
}; 

template <> 
struct dispatch<b> 
{ 
    auto get(db& x) -> decltype(x.get_all_b()) { return x.get_all_b(); } 
}; 

template <> 
struct dispatch<c> 
{ 
    auto get(db& x) -> decltype(x.get_all_c()) { return x.get_all_c(); } 
}; 

template <class data_type> 
auto get_data() -> decltype(dispatch<data_type>{}.get(db)) 
{ 
    return dispatch<data_type>{}.get(db); 
} 
+0

Leider verwendet das Projekt Visual Studio 2013, was bedeutet, dass ich mehr oder weniger auf C++ 11 beschränkt bin. EDIT: dieser Kommentar wurde geschrieben, bevor die C++ 14-Lösung kam, ich werde es versuchen. – user2426460

+0

@ user2426460: eine C++ 11-Lösung hinzugefügt. –

Verwandte Themen