Consider the following system:
template<typename T>
struct wrapper
{
operator T * () { return nullptr; }
};
template<typename Ret, typename T>
Ret func(T);
template<>
int func(float * in)
{
std::cout << "long";
}
template<>
long func(float * in)
{
std::cout << "int";
}
The purpose of the wrapper is to allow it to decay to the type it is templated to (it is a wrapper around a buffer of the type). Moreover, i have a set of functions that are templated specializations of a template. This is to circumvent the usual error when overloading based on only the return type.
This doesn't work though, as noted here:
// the following should work, but doesn't because it's instantiating
// the func<ret, wrapper<float>> which doesn't exist resulting in a linker error
// instead of selecting the int func(float *) overload
wrapper<float> w;
func<int>(w);
Conversely, i would like this to generate a compile-time error (but again, it's generating a link-time error):
// the following should generate a compile-time error
// since no explicit overload for int func(int *) exists
wrapper<int> w2;
func<int>(w2);
So ideally, i would like to disable the original template (maybe through sfinae if this is possible?) such that the overload resolution only considers the explicit specializations, and generates a compile-time error if no match is found. Can this be done?
A portable solution between clang and msvc is a must, but I'm using the newest versions of both.
Another approach may be to use static_assert:
template<typename Ret, typename T>
Ret func(T) {
static_assert(false, "template specialization required");
}
If you do
template<typename Ret> Ret func(float*);
it works as expected: Live example
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