Why compiler can deduce T with this code:
#include <vector>
template<typename T>
void foo(T& t) {}
int main(void) {
std::vector<uint8_t> vec = { 1,2,3 };
foo(vec);
return 0;
}
But fails with this code:
#include <vector>
#include <type_traits>
template<typename T>
void foo(typename std::enable_if<true, T>::type& t) {}
int main(void) {
std::vector<uint8_t> vec = { 1,2,3 };
foo(vec);
return 0;
}
I want to use second construct, to select between two template functions, based on passed class method existence.
In the second case you have a non-deduced context , in other words, the compiler cannot deduce the type.
The simplest example of a non-deduced context is
template<typename T>
struct Id
{
using type = T;
};
template<typename T>
void foo(typename Id<T>::type arg); // T cannot be deduced
As explained by vsoftco, you have a non-deduced context.
For SFINAE, you may use one of the following:
template<typename T>
std::enable_if_t<condition_dependent_of_T, ReturnType>
foo(T& t) {}
or
template<typename T, std::enable_if_t<condition_dependent_of_T>* = nullptr>
ReturnType foo(T& t) {}
To visualize the problem let's analyse an example:
template <class>
struct foo {
using type = float;
};
template <>
struct foo<bool> {
using type = int;
};
template <>
struct foo<int> {
using type = int;
};
template <class T>
void bar(foo<T>::type t) { }
int main() {
bar(int{});
}
Now in the line bar(int{});
both types bool
as well as int
matches to a template parameter T
. Which one value should be deduced then? This is only the one example why non-deduced context is strictly necessary!
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.