In C , std::enable_if is a metafunction that allows for conditional template enablement based on certain constraints. It has recently been superseded by the more concise std::enable_if_t. However, when attempting to port existing code to use the new syntax, some users encounter unexpected redefinition errors.
Example Code
Consider the following code written using std::enable_if:
template<typename T, typename std::enable_if<std::is_same<int, T>::value>::type* = nullptr> void f() { } template<typename T, typename std::enable_if<std::is_same<double, T>::value>::type* = nullptr> void f() { }
This code successfully compiles, with separate specializations for int and double. Now, suppose we want to rewrite this using the std::enable_if_t syntax:
template<typename T, typename = std::enable_if_t<std::is_same<int, T>::value>> void g() { } template<typename T, typename = std::enable_if_t<std::is_same<double, T>::value>> void g() { }
Unexpected Error
Contrary to expectations, this updated code fails to compile, with GCC 5.2 reporting:
error: redefinition of 'template<class T, class> void g()' void g() { }
Explanation
The error lies in the fact that std::enable_if_t represents a type, not a condition. When used as a template argument, it specifies a type constraint. In the original std::enable_if case, the second template parameter is a pointer type, whereas in the std::enable_if_t version, it becomes a type alias. This results in two different template arguments with the same type (void()).
Solution
To avoid this ambiguity, we need to ensure that the second template parameter represents a unique type constraint. One way to achieve this is to use a dummy template parameter:
template<typename T, typename U = std::enable_if_t<std::is_same<int, T>::value>> void g() { } template<typename T, typename U = std::enable_if_t<std::is_same<double, T>::value>> void g() { }
In this case, U is a dummy parameter that serves solely to differentiate the two template arguments. With this modification, the code will compile successfully.
The above is the detailed content of Why do I get redefinition errors when using std::enable_if_t in template arguments?. For more information, please follow other related articles on the PHP Chinese website!