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.