2

I have a function which is almost the same for double and int input. I have therefore overloaded the function for the two types. Unfortunately, at the core, there is a difference between the double and the int variants. Currently, I depend on an overloaded 'core' function for this. To enhance readability I would like to have the overloaded (very short) core functions as part of the function itself, for example using a lambda function.

This example below summarizes my current layout (of course the real code is a bit more involved).

#include <iostream>
#include <cstdlib>

double func_core ( double a, double b ) {
  return a*b;
}

int func_core ( int a, int b ) {
  if ( a==b )
    return 1.;
  else
    return 0.;
}

template <class T> T func ( T a, T b ) {
  return func_core(a,b);
}

int main ( void ) {
  std::cout << func(10 ,20 ) << std::endl;
  std::cout << func(10.,20.) << std::endl;
  return 0;
}

For reasons beyond this example I use C++14 (consistent with this I compiled this example using clang++ -std=c++14 example.cpp).

Now, I want to get rid of the core-function (func_core in this example) because it reduces the readability of my code. Ideally I want to use a lambda function that is overloaded within the function itself. I have summarized my thoughts in the example below (that is not working).

template <class T> T func ( T a, T b ) {
  if ( sizeof(T)==sizeof(int) )
    auto func_core = [](int a,int b){ if (a==b) return 1.; else return 0.; };
  else if ( sizeof(T)==sizeof(double) )
    auto func_core = [](double a,double b){ return a*b; };
  else
    throw std::runtime_error("Overload type not allowed");

  return func_core(a,b);
}

Can this be done? Or am I over-stretching?

3
  • And what if sizeof(T) == sizeof(int) but T is not int (it could be float for example)? How about readability and maintainability? Can you perhaps elaborate on why you want to remove the func_core overloads? What is the actual problem that will solve? Commented Apr 10, 2017 at 8:30
  • @Someprogrammerdude. Fair point, I added an exception. As to why I want this, I have many of these 'core' functions that belong to one function at a time (as they are similar, but slightly different). The proposed approach would avoid the suggestion that these 'core' functions are re-useable entities. Commented Apr 10, 2017 at 8:36
  • 1
    I would suggest you to use en.cppreference.com/w/cpp/language/partial_specialization Commented Apr 10, 2017 at 8:39

2 Answers 2

5

Unfortunately, either with C++11 or C++14 you'd to play with beasts like SFINAE or overload resolution to acomplish what you want.

In C++17 however you could use constexpr if and merge all the desired functionality into one function template as:

template<typename T>
 T func (T const &a, T const &b) {
  if constexpr(std::is_integral<T>::value)
    return (a == b)? 1 : 0;
  else
    return a * b;
}

Live Demo

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for this good suggestion. Do you also have a suggestion when I don't directly return after evaluating what I referred to as func_core? E.g. func_core adds to some variable in a for loop. (In hind-sight I should have included this in the example, but now I would ruin this feed.)
That should work well in C++11/14, too, if leaving out the constexpr there: std::is_integral<T>::value is still a compile time constant and the compiler should optimise away the if and the unused path.
2

You can use type traits

template <class T> T func ( T a, T b ) {
    if (std::is_integral<T>::value)
        if (a==b) return 1;
        else return 0;
    else if (std::is_floating_point<T>::value)
        return a*b;
    else
        throw std::runtime_error("Overload type not allowed");
}

Anyway, i think that best way is avoid lambdas and use normal function overloading.

2 Comments

This would not yet reach my objective: the variable func_core goes out-of-scope before it is evaluated.
@TomdeGeus true, maybe you should inline the function. It's the same actually, i'll edit

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.