Consider the code below. My intention is to use a different conversion operator(implicit) depending on the template type argument of struct B
.
#include <type_traits>
#include <iostream>
using namespace std;
// just to simplify syntax
template <bool Tp_bool, typename Tp = void>
using Enable_if = typename std::enable_if<Tp_bool, Tp>::type;
template<typename T>
struct B {
T m_value;
explicit B(T val = T{}) :
m_value{val}
{ }
template<typename Q = T, Enable_if<sizeof(Q) < sizeof(int), int> = 0 >
operator size_t(){
cout << "narrow T\n";
return static_cast<size_t>(m_value);
}
template<typename Q = T, Enable_if<sizeof(Q) >= sizeof(int), int> = 0 >
operator Q(){
cout << "wide T\n";
return m_value;
}
};
int main() {
B<int> b{5};
char* pc = new char[b]; // !!!compile-time error here!!!
if(b == 5) /*no-op*/; // unrem the line above to see that SFINAE works fine
return 0;
}
This is the error I get on the line I indicated in the code block above:
error: default type conversion can't deduce template argument for
'template<class Q, typename std::enable_if<(sizeof (Q) >= sizeof (int)), int>::type <anonymous> >
B<T>::operator Q() [with Q = Q;
typename std::enable_if<(sizeof (Q) >= sizeof (int)), int>::type <anonymous> = <enumerator>; T = int]'
What is causing this, and how can I make it work?