我有一个模板化的功能
template <typename S, typename T>
string DoStuff(const S& s, const T& t, const string& format) {
...
}
但format
完全改变了函数的行为(想象“csv”,“json”等值)。因此,拥有单独的函数会更有意义。
我觉得我错过了一些明显的东西,这应该可以通过某种专业化来实现。否则,我只需添加一个调度函数,它可以工作,但感觉我错过了一些明显的东西。
template <typename S, typename T>
string DoStuff(const S& s, const T& t, const string& format) {
if (format == "csv")
return DoStuffCSV(s, t);
if (format == "json")
return DoStuffJSON(s, t);
// ...
}
template <typename S, typename T>
string DoStuffCSV(const S& s, const T& t) {
...
}
template <typename S, typename T>
string DoStuffJSON(const S& s, const T& t) {
...
}
从概念上讲,我想要这个(当然这不起作用)
template <typename S, typename T, string("csv")>
string DoStuff(const S& s, const T& t) {
...
}
template <typename S, typename T, string("json")>
string DoStuff(const S& s, const T& t) {
...
}
答案 0 :(得分:3)
只要您想依赖于只能在运行时确定的值,您就不会遗漏任何内容:编译时专业化根本不可能。
但是,正如评论者所建议的那样,可以根据编译时已知的值进行专门化,如枚举。
答案 1 :(得分:2)
正如@bolov和@Nathan Oliver所写,你可以用枚举来做到这一点。
要在编译时分支,我会添加std::integral_constant
:
#include <type_traits>
enum class type
{
txt = 1,
cst = 2,
};
using txt_specifier = std::integral_constant<type, type::txt>;
using csv_specifier = std::integral_constant<type, type::csv>;
后两个是 types ,你可以在编译时重载它们(并使用数值,如果需要的话,可以进行奇特的元编程)。
答案 2 :(得分:0)
如果要选择具有运行时值的正确代码,则可能需要某种调度表:
const auto dispatch = []{
std::map<std::string,std::function<string(const S&,const T&)>> table;
table("csv") = [](const S& s,const T& t) { return do_stuff_csv(s,t); };
table("json") = [](const S& s,const T& t) { return do_stuff_json(s,t); };
return table;
}();
这是一个让读者充分概括这一点的练习,并负责验证format
参数......