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