Suppose you have an enum class
called Func
, a class with a Func
attribute and a Functions
class containing a function template compute
:
enum class Func
{
Sin,
Cos
// Others...
}
class Functions
{
public:
template<Func fn>
static inline double compute(const std::vector<double>& _args);
}
template<>
inline double compute<Func::Sin>(const std::vector<double>& _args)
{
return std::sin(std::accumulate(_args.begin(), _args.end(), 0.0));
}
template<>
inline double compute<Func::Cos>(const std::vector<double>& _args)
{
return std::cos(std::accumulate(_args.begin(), _args.end(), 0.0));
}
// More specialisations...
class Foo
{
private:
Func func;
double result;
public:
inline void compute(const std::vector<double>& _args)
{
result = Functions::compute<func>(_args);
// A few other operations follow.
}
}
I would like to call the appropriate specialised template from Functions
by passing the func
attribute. However, this doesn't work because func
is not known at compile time. I get the following error in clang
:
candidate template ignored: invalid explicitly-specified argument for template parameter 'fn'
^
I believe that I can achieve this by making the compute
method in Foo
a template as well and specialising for each Func
:
class Foo
{
private:
Func func;
double result;
public:
template<Func fn>
inline void compute(const std::vector<double>& _args)
{
result = Functions::compute<fn>(_args);
// A few other operations follow.
}
}
template<>
inline void compute<Func::Sin>()(const std::vector<double>& _args)
{
result = Functions::compute<Func::Sin>(_args);
}
template<>
inline void compute<Func::Cos>()(const std::vector<double>& _args)
{
result = Functions::compute<Func::Cos>(_args);
}
// Etc.
However, this defeats the purpose because I would like to use the func
attribute in Foo
. Also, I would like to avoid the double handling because Foo::compute()
performs a few more operations, which I would have to copy into each specialisation.
Is there any way to achieve this functionality by using the func
attribute?
Aucun commentaire:
Enregistrer un commentaire