简体   繁体   中英

C++ template parameter deduction fails

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM