Home > Backend Development > C++ > How to Select a Member Function Based on a Template Parameter Using `enable_if`?

How to Select a Member Function Based on a Template Parameter Using `enable_if`?

DDD
Release: 2024-10-25 19:06:39
Original
860 people have browsed it

How to Select a Member Function Based on a Template Parameter Using `enable_if`?

Selecting a Member Function Using Enable_If Conditions

The task is to determine the invocation of a member function based on a class template parameter. The following code snippet attempts to achieve this:

<code class="cpp">#include <iostream>
#include <type_traits>

template<typename T>
struct Point
{
  void MyFunction(typename std::enable_if<std::is_same<T, int>::value, T &>::type* = 0)
  {
    std::cout << "T is int." << std::endl;
  }

  void MyFunction(typename std::enable_if<!std::is_same<T, int>::value, float &>::type* = 0)
  {
    std::cout << "T is not int." << std::endl;
  }
};</code>
Copy after login

However, this code fails to compile with the error "no type named ‘type’ in ‘struct std::enable_if’".

SFINAE in Action

The key to understanding this issue lies in the concept of Substitution Failure Is Not An Error (SFINAE). Enable_if allows conditional compilation based on template arguments. In this case, the template argument T is already known when the member functions are instantiated. Therefore, the condition is evaluated at instantiation time and the corresponding function is selected.

Fixing the Code

To rectify this, we need to introduce a dummy template argument that is defaulted to T. This allows the SFINAE mechanism to work as intended. The modified code would look like this:

<code class="cpp">template<typename T>
struct Point
{
  template<typename U = T>
  typename std::enable_if<std::is_same<U, int>::value>::type
    MyFunction()
  {
    std::cout << "T is int." << std::endl;
  }

  template<typename U = T>
  typename std::enable_if<std::is_same<U, float>::value>::type
    MyFunction()
  {
    std::cout << "T is not int." << std::endl;
  }
};</code>
Copy after login

Preventing Explicit Member Function Specialization

As pointed out by HostileFork, the original code allows the explicit specification of template arguments for the member functions, which could lead to incorrect results. To prevent this, we can add a static_assert that checks if any template arguments are provided. This ensures that the correct member function is always invoked based on the template argument T. The modified code would be:

<code class="cpp">template<typename T>
struct Point
{
  template<typename... Dummy, typename U = T>
  typename std::enable_if<std::is_same<U, int>::value>::type
    MyFunction()
  {
    static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
    std::cout << "T is int." << std::endl;
  }

  template<typename... Dummy, typename U = T>
  typename std::enable_if<std::is_same<U, float>::value>::type
    MyFunction()
  {
    static_assert(sizeof...(Dummy)==0, "Do not specify template arguments!");
    std::cout << "T is not int." << std::endl;
  }
};</code>
Copy after login

The above is the detailed content of How to Select a Member Function Based on a Template Parameter Using `enable_if`?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template