I have a templated function
template <typename S, typename T>
string DoStuff(const S& s, const T& t, const string& format) {
...
}
But format
changes the function's behaviour completely (imagine values like "csv", "json", etc.). So it would make a bit more sense to have separate functions.
I feel like I'm missing something obvious, that this should be possible with some sort of specialisation. Otherwise, I just have to add a dispatch function, which would work but feels like I've missed something obvious.
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) {
...
}
Conceptually, I want this (which of course doesn't work)
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) {
...
}
So long as you want to depend on a value that can only be determined at run time, you're not missing anything: compile-time specialization is simply impossible.
However, as suggested by commenters, you can specialize according to a value that's known at compile-time, like an enum.
As @bolov and @Nathan Oliver write, you can do this with an enum.
To branch at compile time, I'd add 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>;
The latter two are types , and you can overload on them at compile time (and using the numeric values, do fancy metaprogramming things if needed further).
If you want to select the correct code with a run-time value, you probably need some sort of despatch table:
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;
}();
It's an exercise for the reader to generalise this sufficiently, and to take care of validating the format
parameter...
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.