Home  >  Article  >  Backend Development  >  Why do I get redefinition errors when using std::enable_if_t in template arguments?

Why do I get redefinition errors when using std::enable_if_t in template arguments?

Patricia Arquette
Patricia ArquetteOriginal
2024-11-27 02:23:14954browse

Why do I get redefinition errors when using std::enable_if_t in template arguments?

Anomalous Redefinition Errors with std::enable_if_t in Template Arguments

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!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn