We are familiar with overloading based on function parameters. But why can't we have overloading based on non-type template parameters? With such overloading, you don't have to add extra function parameters just for overloading purposes, which may have a negative impact on runtime performance. Alas, the following code does not compile:
template <bool>
void func() {}
template <int>
void func() {}
int main() {
func<0>();
}
The error message produced is
error: call of overloaded 'func()' is ambiguous
func<0>();
^
note: candidate: void func() [with bool <anonymous> = false]
void func() {}
^
note: candidate: void func() [with int <anonymous> = 0]
void func() {}
^
Note that this may be more efficient than
void func(bool) {}
void func(int) {}
Is there any problem in allowing this usage?
If you are open to a bit of added syntax, you can use:
// No default implementation.
template <typename T, T value> struct Impl;
// Implement the bool/true version
template <> struct Impl<bool, true>
{
void operator()() {}
};
// Implement the bool/false version
template <> struct Impl<bool, false>
{
void operator()() {}
};
// Implement the int version
template <int N> struct Impl<int, N>
{
void operator()() {}
};
template <typename T, T value>
void func()
{
Impl<T, value>()();
};
int main()
{
func<bool, true>();
func<int, 10>();
}
Disclaimer
I have no idea whether this will perform better than calling func(true)
.
Andrei Alexandrescu wrote about this in "Modern C++ Design", IIUC, and it looks like std::integral_constant
can basically give nearly the effect you want, no? What would be the major improvements over the following? It basically allows to overload on (at least integral types of) constants.
#include <type_traits>
using tt = std::integral_constant<bool, true>;
constexpr tt t;
using ft = std::integral_constant<bool, false>;
constexpr ft f;
void func(tt) {};
void func(ft) {};
int main()
{
func(t);
return 0;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With