如果出现以下问题
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();
...
}
我有一个很长的函数,需要做类似的事情(我可以为这3个数据集中的每个数据集编写一个模板,它采用类型a,b或c),并且有一个db实例。唯一的问题是数据访问。我想通过写一些东西来解决这个问题:
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);
这可能有多种原因导致失败,但我希望它确实展示了我想要实现的目标。
根据建议,我将添加一个所需的用法示例:
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);
}
答案 0 :(得分:1)
C ++ 17解决方案:
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解决方案:
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解决方案:
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);
}