简体   繁体   中英

Template argument deduction and pointers to constants

I had defined two overloaded functions, their declarations are as follows

template <class T> void Foo(const T *p);    // lets call this Foo_p

template <class T> void Foo(const T& r);    // lets call this Foo_r

When I call

Foo( ptr_to_non_const );

Foo_r gets called. I assumed that constant qualification are stripped away from pointers when looking for best match. Since T* is more specialized than T& I expected that Foo_p will be called.

Could anyone point me to a good resource that lists template argument deduction rules and the precedence of matches.

In this particular case I intend template <class T> void Foo(const T& r) to be called for non-pointer type. Does it mean I have to define the functions with and without const qualifications. For one argument it is not a big deal, but my function take more than one pointer, so I would want to avoid the repition. Any suggestions would be appreciated.

The template deduction rules are quite complicated and I'm not sure if there is anywhere a simple summary. However, if two templates are candidates and one of them requires a conversion while the other does not, the one not requiring a conversion to produce the template argument is chosen. In your example, the matching instantiations are thus:

S* ptr_to_non_const = ...;
Foo(ptr_to_non_const); // => candidates:
                       //   a. F(const T&) with `T` deduced as `S*` requires no
                       //      conversion
                       //   b. F(const T*) with `T` deduced as `S` requires `S*` to
                       //      `S const*` conversion

To force the use of the pointer overload, you can remove the reference version from the overload set using std::enable_if<...> together with std::is_pointer<...> :

template <class T>
typename std::enable_if<!std::is_pointer<T>::value>::type
Foo(const T& r);

Although this uses the C++ 2011 features, both std::enable_if<...> and std::is_pointer<...> can be implemented quite easy with a C++ 2003 compiler, as well (and I'm pretty sure that Boost has done so).

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