How to prevent function template argument deduction

174 Views Asked by At

This is a toy example but it illustrates the point I guess ... I need to be sure a templated function (can be a class member) is invoked only and only if the argument type is specified, since the specialization will be different for the several chosen types.

#include <type_traits>

template<typename T>
void ff(T x) { cout << "NO WAY!!! : " << x << endl; }

template<>
void ff(uint16_t x) { cout << "uint16_t thing: " << x << endl; }

template<>
void ff(uint32_t x) { cout << "uint32_t thing: " << x << endl; }

// ----------------------------------------------------------

Compiling and running the example, it produces:

ff<uint16_t>(10); // -> uint16_t thing: 10

ff(10); // -> NO WAY!!! : 10 ... This is the case I'm trying to avoid ...

To forbid the compilation of the second function call I've replaced the first declaration with:

template<typename T>
void ff(std::type_identity_t<T> && x) { cout << "NO NO NO! : " << x << endl; }

But it fails to compile ...

error: template-id ‘ff<>’ for ‘void ff(uint16_t)’ does not match any template declaration

(gcc 12.3.0)

How can it be done?

Thanks!

1

There are 1 best solutions below

0
francisC On

How to do it ...

PS: Your comments lead me to the right track!

Of course there's no need to use templates on simple functions, but if we have a class with template member functions it can be handy ;-)

The only missing thing was the template arg type at ff<T>() specialization ...

#include <type_traits>

template<typename T>
void ff(std::type_identity_t<T> x) { /* force arg type */ }

template<>
void ff<uint16_t>(uint16_t x) { cout << "uint16_t thing: " << x << endl; }

template<>
void ff<uint32_t>(uint32_t x) { cout << "uint32_t thing: " << x << endl; }

Now, let's compile:

ff(10)                       // no template arg type -> ERROR
ff<uint16_t>(10);            // Ok! it compiles :-)

Yes, I wanted to compiler to give an error if the template type was missing, forcing me to specify it, something it does now.

Thank you all, you've been most helpful!

The terse link to type_traits at cppreference.com is the following:

https://en.cppreference.com/w/cpp/types/type_identity