简体   繁体   中英

Couldn't deduce template parameter 'T' for function arguments using std::conditional

Given this piece of code:

#include <type_traits>

template<typename T>
auto sqr(typename std::conditional<sizeof(T) <= sizeof(int), T, const T&>::type a)
{return a*a;}

int main(void)
{
    auto x = sqr<int>(10); //works
    auto y = sqr(10);      //ERROR: couldn't deduce template parameter 'T'
}

What causes the automatic type deduction fail when calling sqr(10) ? Is there a way I can call sqr() without explicitly defining the type?

You have an undeduced context here. To give an intuition as to why, note that ::type must be the actual type of 10 , but you want it to depend on the type of 10 indirectly. So the parameter type cannot be used to deduce the result of std::conditional .

If you seek to "optimize" functions to pass by value, the solution is overloading with SFINAE.

template<typename T, typename = std::enable_if_t<(sizeof(T) > sizeof(int))>> // base case
auto sqr(const T& a)
{return a*a;}

template<typename T, typename = std::enable_if_t<sizeof(T) <= sizeof(int)>> // more refined case case
auto sqr(T a)
{return a*a;}

Alternatively, and to support more conditions, you can use std::enable_if_t to add a SFINAE friendly non-type parameter (for example a pointer). As @Jarod42 suggested:

template<typename T, std::enable_if_t<sizeof(T) <= sizeof(int), int*> = nullptr>
auto sqr(T a)
{return a*a;}

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