3 ms·
Exactly. I imagine it's something like the following: #include <iostream> #include <string> #include <utility> namespace sp { template <typename T>
by souperhanz 11y ago
Exactly. I imagine it's something like the following:
#include <iostream>
#include <string>
#include <utility>
namespace sp {
template <typename T>
struct option {
template <typename U>
option(U&& u) : mValue(std::forward<U>(u)) {}
const T& getValue() const { return mValue; }
private:
T mValue;
};
struct shell : option<bool> { using option<bool>::option; };
struct output : option<std::string> { using option<std::string>::option; };
struct options {
bool mShell;
std::string mOutput;
};
void applyOpt(options& opts, const shell& opt)
{
opts.mShell = opt.getValue();
std::cout << "shell=" << (opts.mShell ? "true" : "false") << '\n';
}
void applyOpt(options& opts, const output& opt)
{
opts.mOutput = opt.getValue();
std::cout << "output=" << opts.mOutput << '\n';
}
void applyOpts(options&) {}
template <typename HeadOpt, typename... TailOpts> void applyOpts(options& opts, HeadOpt&& headOpt, TailOpts&&... tailOpts)
{
applyOpt(opts, std::forward<HeadOpt>(headOpt));
applyOpts(opts, std::forward<TailOpts>(tailOpts)...);
}
template <typename... Opts> int call(std::initializer_list<const char*> args, Opts&&... opts)
{
std::cout << "args=";
const char* sep = "";
for (auto&& s : args)
{
std::cout << sep << s;
sep = " ";
}
std::cout << '\n';
options options;
applyOpts(options, std::forward<Opts>(opts)...);
return 0;
}
}
int main()
{
sp::call({"ls", "-l"}, sp::shell{true}, sp::output{"foo.txt"});
return 0;
}
- ant6n 11y agoOh neat. Also thanks for reducing the use to a 'small' example. Why does the author use a struct and "shell{true}" rather than creating a function or a class that would allow "shell(true)". Love for braces? Performance? EDIT: also I wonder whether there's a way to create helper definitions to allow defining named parameters like this in a more concise way. This recursive template expansion business tends to result in long code.
- ant6n 11y agoOk, so it seems the use of braces (use of "Uniform initialization syntax") in constructors is to reduce the ambiguity with declaring functions and declaring+initializing variables. This wiki entry has more: https://en.wikipedia.org/wiki/Most_vexing_parse https://en.wikipedia.org/wiki/Most_vexing_parse
- souperhanz 11y agoIt's a very good day. I get to just say "exactly" again. :)
- Fede_V 11y agoThanks for taking the time to explain that :)