I'd like to add same number pointers from typename U to typename T, for example when T = int*** and U = int*, the result is int****. So, I write the following:
#include <type_traits>
template <typename T, typename U,
typename std::enable_if_t<std::is_pointer<U>::value>* = nullptr>
auto addPointer(T, U)
-> decltype(addPointer(std::declval<std::add_pointer_t<T>>(),
std::declval<std::remove_pointer_t<U>>()));
template <typename T, typename U,
typename std::enable_if_t<!std::is_pointer<U>::value>* = nullptr>
auto addPointer(T, U) -> T;
int main()
{
using t =
decltype(addPointer(std::declval<int***>(), std::declval<int*>()));
}
and I get the following on Linux clang 3.7:
$ clang++ -std=c++14 -stdlib=libc++ -lc++abi -Wall -Wextra a.cpp
a.cpp:16:18: error: no matching function for call to 'addPointer'
decltype(addPointer(std::declval<int***>(), std::declval<int*>()));
^~~~~~~~~~
a.cpp:5:6: note: candidate template ignored: substitution failure [with T = int ***, U =
int *, $2 = nullptr]: call to function 'addPointer' that is neither visible in the
template definition nor found by argument-dependent lookup
auto addPointer(T, U)
^
/usr/bin/../include/c++/v1/type_traits:244:78: note: candidate template ignored: disabled
by 'enable_if' [with T = int ***, U = int *]
...<bool _Bp, class _Tp = void> using enable_if_t = typename enable_if<_Bp, _Tp>::type;
^
1 error generated.
Why do I get the error?
As we're dealing with scalars, ADL will not look in the global namespace. Not only can the fallback overload not be found this way, the overload you're currently defining cannot be referred to in the trailing-return-type.
With C++14, there is a nicer solution to your problem, which circumvents that issue:
template <typename T>
T addPointer(T, ...);
template <typename T, typename U>
auto addPointer(T t, U* u) {return addPointer(&t, *u);}
Demo.
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