James James - 25 days ago 8
C++ Question

Using namespace and using directive not working for std::enable_if_t

When I tried to compile the following code using MSCL 19, it's OK. However, when I tried g++ 6.2.0 and clang 3.9.0, I got an error like

expected nested-name-specifier class=typename


#include<type_traits>
using namespace std;
template<class T,class=typename enable_if_t<
is_signed<T>::value&&is_integral<T>::value&&(sizeof(T)>1)>>
void f(T i) {}
int main() {
f(1);
}


Adding
using std::enable_if_t
will produce the same result.

#include<type_traits>
using namespace std;
using std::enable_if_t;
template<class T,class=typename enable_if_t<
is_signed<T>::value&&is_integral<T>::value&&(sizeof(T)>1)>>
void f(T i) {
}
int main(){
f(1);
}


This issue can be solved by prefixing the
enable_if_t
with
std::
:

#include<type_traits>
using namespace std;
template<class T,class=typename std::enable_if_t<
is_signed<T>::value&&is_integral<T>::value&&(sizeof(T)>1)>>
void f(T i) {
}
int main(){
f(1);
}


Why the
using namespace std
and
using std::enable_if_t
are invalid to
std::enable_if_t
?

dvk dvk
Answer

What it tries to tell you is when it sees typename it expects a nested type specifier next. And enable_if_t is used without any nesting (no ::). Removing typename makes it work with gcc.