Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should one overload functions with const/non-const parameters?

I have the following code:

// string specializations
void foo(const char *a, const char *b);
void foo(const char *a, const std::string &b);
void foo(const std::string &a, const char *b);
void foo(const std::string &a, const std::string &b);

// generic implementation
template<typename TA, typename TB>
void foo(TA a, TA b)
{...}

The problem is that this test case:

char test[] = "test";
foo("test", test);

ends up calling the templated version of foo. Obviously, I can just add a few more overloads with various mixes of non-const parameters, but I want to know: is there's a better way to overload foo such that it is specialized on all const and non-const pairings of strings? One that doesn't require me to hope I haven't missed some permutation of argument types?

like image 584
moswald Avatar asked Nov 15 '12 01:11

moswald


People also ask

Can const functions be overloaded?

Overloading on the basis of const type can be useful when a function return reference or pointer. We can make one function const, that returns a const reference or const pointer, other non-const function, that returns non-const reference or pointer.

Can we overload const functions in C++?

C++ allows member methods to be overloaded on the basis of const type. Overloading on the basis of const type can be useful when a function returns a reference or pointer.

What are the conditions to overload a function?

Rules of Function Overloading in C++The functions must have the same name. The functions must have different types of parameters. The functions must have a different set of parameters. The functions must have a different sequence of parameters.

How is it possible to have both const and non-const version of a function?

There are legitimate uses of having two member functions with the same name with one const and the other not, such as the begin and end iterator functions, which return non-const iterators on non-const objects, and const iterators on const objects, but if it's casting from const to do something, it smells like fish.


1 Answers

Thanks to Mooing Duck's suggestion, this is my solution:

// string specialization
void foo(const std::string &a, const std::string &b);

template<typename TA, typename TB>
typename std::enable_if<
    std::is_constructible<std::string, TA>::value &&
    std::is_constructible<std::string, TB>::value
>::type foo(TA a, TB b)
{
    foo(std::string(std::move(a)), std::string(std::move(b)));
}

// generic implementation
template<typename TA, typename TB>
typename std::enable_if<
    !std::is_constructible<std::string, TA>::value ||
    !std::is_constructible<std::string, TB>::value
>::type foo(TA a, TB b)
{...}
like image 184
moswald Avatar answered Sep 27 '22 23:09

moswald