c++ - typename to function name mapping at compile time -


things want achieve similar in post: select function name based on template parameter

in c library, handle different numeric types (float, double, complex -float, complex-double), there functions different names.

when creating wrapper of such c library, figure out way achieve effect of overloading , use same function name numeric types. use template specialization:

#include <iostream>  float saxpy(float x) {     return (1-x); }  double daxpy(double x) {     return (1+x); }  template <typename t>  t axpy(t x);  template<> inline float axpy<float>(float x) {     return saxpy(x); }  template<> inline double axpy<double>(double x) {     return daxpy(x); }   int main() {      auto z0 = axpy(1.0f);     auto z1 = axpy(1.0);      std::cout << z0 << " " << z1 << std::endl;      return 0; } 

there's way using type traits:

#include <type_traits> #include <iostream>  float saxpy(float x) {     return (1-x); }  double daxpy(double x) {     return (1+x); }   struct saxpy_traits {     static float feval(float x) { return saxpy(x); } };  struct daxpy_traits {     static double feval(double x) { return daxpy(x); } };   template <typename t> struct axpy_traits {     typedef typename std::conditional<std::is_same<t, float>::value, saxpy_traits, daxpy_traits>::type func;     inline static t feval(t x) {          return func::feval(x);      } };  template<typename t> inline t axpy(t x) {     return axpy_traits<t>::feval(x); }   int main() {      auto z0 = axpy(1.0f);     auto z1 = axpy(1.0);      std::cout << z0 << " " << z1 << std::endl;      return 0; } 

is there more elegant ways? thank you.

since don't know qualifies "elegant", propose 2 alternative approaches:

float saxpy(float x) {   return 1.0f - x; }    double daxpy(double x) {   return 1.0 + x; }    namespace v1 {  float axpy(float x) { return saxpy(x); }  double axpy(double x) { return daxpy(x); }  } // namespace v1    namespace v2 {  struct axpy {   float operator()(float x) const { return saxpy(x); }    double operator()(double x) const { return daxpy(x); } };  static constexpr axpy axpy;  } // namespace v2 

the first version defines 2 overloaded functions. similar approach taken standard library, e.g. std::sqrt.

the second version defines function object has overloaded operator(). version allows code auch as

  std::vector<float> fs { 1.f, 2.f, 3.f, 4.f };   std::vector<float> rs(fs.size());   std::transform(fs.begin(), fs.end(), rs.begin(), v2::axpy); 

which not compile first version.


Comments