简体   繁体   中英

Const'ing a parameter to overload functions in C++

I am writing array functions** (eg transpose) and often want to have both in situ and ex situ versions of the same function. The in situ version is faster but changes the original array. The ex situ version is used if you need to keep the original unchanged, but it's slower since it has to make a copy. I would like the two versions of the function to have the same name, but I know you can't distinguish functions in C++ by return type alone. I thought of a way of doing it by changing the array parameter into a const for the ex situ version, but I'm concerned there may be issues with this approach since I couldn't find it mentioned anywhere (eg Overload a C++ function according to the return value )

// in situ version
void square(int* ip, int size)
{
  for (int i = 0; i < size; i++)
    ip[i] *= ip[i];
}

// ex situ version
int* square(int const* icp, int size)
{   
  int* ip = new int[size];

  for (int i = 0; i < size; i++)
    ip[i] = icp[i] * icp[i];

  return ip;
}

// usage
int main()
{
  int a[5] = {0, 1, 2, 3, 4};

  square(a, 5);
  // now a = {0, 1, 4, 9, 16}

  int* b = square(const_cast<int const*>(a), 5);
  // a still = {0, 1, 4, 9, 16}
  // b = {0, 1, 16, 81, 256}
  ...
  delete[] b;
  ...
  return 0;
}

Any feedback much appreciated thanks.

** I'm aware there are standard containers and libraries for doing some of this (std::vector, boost::array). However I'm working on a C++ DLL to be called from Excel/VBA, so the arrays arrive in my C++ program as raw pointers. Since performance is a priority, converting them into standard containers and back is unappealing.

Please don't do that, it's going to confuse your users quite a lot. Make two different functions with two different names.

Write a functor to square it and let the user decide using transform. (In this simple case a function can be used instead of a functor)

template<class T>
T square(const T& x)
{
    return x*x;
}

int *in, *out;
size_t size;

std::transform(in, in + size, out, square<int>); // ex situ
std::transform(in, in + size, in, square<int>); // in situ

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM